コード例 #1
0
 def test_load_migrate_params_even_when_invalid(self):
     workflow = Workflow.create_and_init()
     module_zipfile = create_module_zipfile(
         "mod",
         spec_kwargs={"parameters": [{
             "id_name": "a",
             "type": "string"
         }]},
         python_code=textwrap.dedent("""
             def migrate_params(params):
                 return {"x": "y"}  # does not validate
             """),
     )
     wf_module = workflow.tabs.first().wf_modules.create(
         order=0, slug="step-1", module_id_name="mod", params={"a": "b"})
     with self.assertLogs("cjwstate.params", level=logging.INFO):
         result = self.run_with_async_db(
             fetch.load_database_objects(workflow.id, wf_module.id))
     self.assertEqual(result.migrated_params_or_error, {"x": "y"})
コード例 #2
0
    def test_workflow_anonymous_user(self):
        # Looking at example workflow as anonymous should create a new workflow
        public_workflow = Workflow.create_and_init(
            name="Other workflow public",
            owner=self.otheruser,
            public=True,
            example=True,
        )

        # don't log in
        response = self.client.get("/workflows/%d/" % public_workflow.id)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(
            Workflow.objects.filter(owner=None).count(),
            1)  # should have duplicated the  wf with this API call

        # Ensure the anonymous users can't access the Python module
        self.assertNotContains(response, '"pythoncode"')
コード例 #3
0
 def test_clear_file_upload_api_token(self):
     # Currently, we don't restrict this API to just "upload" modules. We do
     # restrict the actual _uploads_, so this oversight isn't a big deal.
     user = User.objects.create()
     workflow = Workflow.create_and_init(owner=user)
     step = workflow.tabs.first().steps.create(
         module_id_name="x",
         order=0,
         slug="step-1",
         file_upload_api_token="abcd1234")
     response = self.run_handler(
         clear_file_upload_api_token,
         user=user,
         workflow=workflow,
         stepSlug="step-1",
     )
     step.refresh_from_db()
     self.assertResponse(response, data=None)
     self.assertIsNone(step.file_upload_api_token)
コード例 #4
0
    def test_set_notifications(self, log_event):
        user = User.objects.create(username="******", email="*****@*****.**")
        workflow = Workflow.create_and_init(owner=user)
        wf_module = workflow.tabs.first().wf_modules.create(
            order=0, slug="step-1", notifications=False
        )

        response = self.run_handler(
            set_notifications,
            user=user,
            workflow=workflow,
            wfModuleId=wf_module.id,
            notifications=True,
        )
        self.assertResponse(response, data=None)

        wf_module.refresh_from_db()
        self.assertEqual(wf_module.notifications, True)
        log_event.assert_called()
コード例 #5
0
    def test_change_parameters_update_tab_delta_ids(self):
        workflow = Workflow.create_and_init()

        # Build the modules
        create_module_zipfile(
            "x", spec_kwargs={"parameters": [{"id_name": "x", "type": "integer"}]}
        )
        create_module_zipfile(
            "tabby", spec_kwargs={"parameters": [{"id_name": "tab", "type": "tab"}]}
        )
        self.kernel.migrate_params.side_effect = lambda m, p: p

        # tab1's step1 depends on tab2's step2
        step1 = workflow.tabs.first().wf_modules.create(
            order=0,
            slug="step-1",
            module_id_name="tabby",
            last_relevant_delta_id=workflow.last_delta_id,
            params={"tab": "tab-2"},
        )
        tab2 = workflow.tabs.create(position=1, slug="tab-2")
        step2 = tab2.wf_modules.create(
            order=0,
            slug="step-1",
            module_id_name="x",
            last_relevant_delta_id=workflow.last_delta_id,
            params={"x": 1},
        )

        with self.assertLogs(level=logging.INFO):
            cmd = self.run_with_async_db(
                commands.do(
                    ChangeParametersCommand,
                    workflow_id=workflow.id,
                    wf_module=step2,
                    new_values={"x": 2},
                )
            )

        step1.refresh_from_db()
        step2.refresh_from_db()
        self.assertEqual(step1.last_relevant_delta_id, cmd.id)
        self.assertEqual(step2.last_relevant_delta_id, cmd.id)
コード例 #6
0
 def test_set_secret_editor_access_denied(self):
     user = User.objects.create(email="*****@*****.**")
     workflow = Workflow.create_and_init(public=True)
     workflow.acl.create(email=user.email, role=Role.EDITOR)
     create_module_zipfile("g",
                           spec_kwargs={"parameters": [TestStringSecret]})
     step = workflow.tabs.first().steps.create(module_id_name="g",
                                               order=0,
                                               slug="step-1")
     response = self.run_handler(
         set_secret,
         user=user,
         workflow=workflow,
         stepId=step.id,
         param="string_secret",
         secret="foo",
     )
     self.assertResponse(response,
                         error="AuthError: no owner access to workflow")
コード例 #7
0
 def test_complete_happy_path(self, queue_render, send_update):
     send_update.return_value = async_noop()
     queue_render.return_value = async_noop()
     _init_module("x")
     workflow = Workflow.create_and_init()
     wf_module = workflow.tabs.first().wf_modules.create(
         order=0, slug="step-123", module_id_name="x", file_upload_api_token="abc123"
     )
     upload = wf_module.in_progress_uploads.create()
     uuid = str(upload.id)
     key = upload.get_upload_key()
     minio.put_bytes(upload.Bucket, key, b"1234567")
     response = self.client.post(
         f"/api/v1/workflows/{workflow.id}/steps/step-123/uploads/{upload.id}",
         {"filename": "test.csv"},
         content_type="application/json",
         HTTP_AUTHORIZATION="Bearer abc123",
     )
     self.assertEqual(response.status_code, 200)
     # Upload and its S3 data were deleted
     self.assertFalse(minio.exists(upload.Bucket, key))
     upload.refresh_from_db()
     self.assertTrue(upload.is_completed)
     # Final upload was created
     uploaded_file = wf_module.uploaded_files.first()
     self.assertEqual(
         uploaded_file.key, f"wf-{workflow.id}/wfm-{wf_module.id}/{uuid}.csv"
     )
     self.assertEqual(
         minio.get_object_with_data(minio.UserFilesBucket, uploaded_file.key)[
             "Body"
         ],
         b"1234567",
     )
     self.assertEqual(uploaded_file.name, "test.csv")
     # Return value includes uuid
     data = json.loads(response.content)
     self.assertEqual(data["uuid"], uuid)
     self.assertEqual(data["name"], "test.csv")
     self.assertEqual(data["size"], 7)
     # Send deltas
     send_update.assert_called()
     queue_render.assert_called()
コード例 #8
0
ファイル: test_step.py プロジェクト: lenamax2355/cjworkbench
    def test_report_module_error(self):
        workflow = Workflow.create_and_init()
        tab = workflow.tabs.first()
        step = tab.steps.create(
            order=0,
            slug="step-1",
            module_id_name="x",
            last_relevant_delta_id=workflow.last_delta_id,
        )

        module_zipfile = create_module_zipfile(
            "x",
            spec_kwargs={"loads_data": True},
            python_code="def render(table, params):\n  undefined()",
        )

        with self.assertLogs(level=logging.INFO):
            result = self.run_with_async_db(
                execute_step(
                    self.chroot_context,
                    workflow,
                    step,
                    module_zipfile,
                    {},
                    Tab(tab.slug, tab.name),
                    RenderResult(),
                    {},
                    self.output_path,
                ))
        assert_render_result_equals(
            result,
            RenderResult(errors=[
                RenderError(
                    I18nMessage(
                        "py.renderer.execute.step.user_visible_bug_during_render",
                        {
                            "message":
                            "exit code 1: NameError: name 'undefined' is not defined"
                        },
                        None,
                    ))
            ]),
        )
コード例 #9
0
    def test_fetch_result_deleted_file_means_none(self):
        workflow = Workflow.create_and_init()
        tab = workflow.tabs.first()
        wf_module = tab.wf_modules.create(
            order=0,
            slug="step-1",
            module_id_name="x",
            last_relevant_delta_id=workflow.last_delta_id,
        )
        with parquet_file({"A": [1]}) as path:
            so = create_stored_object(workflow.id, wf_module.id, path)
        wf_module.stored_data_version = so.stored_at
        wf_module.save(update_fields=["stored_data_version"])
        # Now delete the file on S3 -- but leave the DB pointing to it.
        minio.remove(minio.StoredObjectsBucket, so.key)

        def render(*args, fetch_result, **kwargs):
            self.assertIsNone(fetch_result)
            return RenderResult()

        module_zipfile = create_module_zipfile(
            "x",
            python_code=textwrap.dedent("""
                import pandas as pd
                def render(table, params, *, fetch_result, **kwargs):
                    assert fetch_result is None
                    return pd.DataFrame()
                """),
        )

        with self.assertLogs(level=logging.INFO):
            self.run_with_async_db(
                execute_wfmodule(
                    self.chroot_context,
                    workflow,
                    wf_module,
                    module_zipfile,
                    {},
                    Tab(tab.slug, tab.name),
                    RenderResult(),
                    {},
                    self.output_path,
                ))
コード例 #10
0
ファイル: test_wf_module.py プロジェクト: afcarl/cjworkbench
    def test_email_delta_ignore_corrupt_cache_error(self, email_delta,
                                                    read_cache):
        read_cache.side_effect = rendercache.CorruptCacheError
        workflow = Workflow.create_and_init()
        tab = workflow.tabs.first()
        wf_module = tab.wf_modules.create(
            order=0,
            slug="step-1",
            module_id_name="x",
            last_relevant_delta_id=workflow.last_delta_id - 1,
            notifications=True,
        )
        # We need to actually populate the cache to set up the test. The code
        # under test will only try to open the render result if the database
        # says there's something there.
        rendercache.cache_render_result(
            workflow,
            wf_module,
            workflow.last_delta_id - 1,
            RenderResult(arrow_table({"A": [1]})),
        )
        wf_module.last_relevant_delta_id = workflow.last_delta_id
        wf_module.save(update_fields=["last_relevant_delta_id"])

        with arrow_table_context({"A": [2]}) as table2:

            def render(*args, **kwargs):
                return RenderResult(table2)

            with self._stub_module(render):
                with self.assertLogs(level=logging.ERROR):
                    self.run_with_async_db(
                        execute_wfmodule(
                            workflow,
                            wf_module,
                            {},
                            Tab(tab.slug, tab.name),
                            RenderResult(),
                            {},
                            Path("/unused"),
                        ))

        email_delta.assert_not_called()
コード例 #11
0
    def test_change_parameters_on_soft_deleted_wf_module(self):
        workflow = Workflow.create_and_init()
        wf_module = workflow.tabs.first().wf_modules.create(
            order=0,
            slug="step-1",
            module_id_name="loadurl",
            last_relevant_delta_id=workflow.last_delta_id,
            is_deleted=True,
            params={"url": ""},
        )

        cmd = self.run_with_async_db(
            commands.do(
                ChangeParametersCommand,
                workflow_id=workflow.id,
                wf_module=wf_module,
                new_values={"url": "https://example.com"},
            ))
        self.assertIsNone(cmd)
コード例 #12
0
    def test_clientside_update(self, send_update):
        future_none = asyncio.Future()
        future_none.set_result(None)
        send_update.return_value = future_none

        workflow = Workflow.create_and_init(selected_tab_position=0)  # tab-1
        tab2 = workflow.tabs.create(position=1, slug="tab-2")
        cmd = self.run_with_async_db(
            commands.do(DeleteTabCommand, workflow_id=workflow.id, tab=tab2))
        delta1 = send_update.call_args[0][1]
        self.assertEqual(delta1.workflow.tab_slugs, ["tab-1"])
        self.assertFalse(delta1.tabs)
        self.assertEqual(delta1.clear_tab_slugs, frozenset(["tab-2"]))

        self.run_with_async_db(commands.undo(cmd))
        delta2 = send_update.call_args[0][1]
        self.assertEqual(delta2.workflow.tab_slugs, ["tab-1", "tab-2"])
        self.assertEqual(list(delta2.tabs.keys()), ["tab-2"])
        self.assertFalse(delta2.clear_tab_slugs)
コード例 #13
0
 def test_complete_upload_not_found(self):
     _init_module("x")
     workflow = Workflow.create_and_init()
     workflow.tabs.first().wf_modules.create(
         order=0,
         slug="step-123",
         module_id_name="x",
         file_upload_api_token="abc123",
         params={"file": None},
     )
     response = self.client.post(
         f"/api/v1/workflows/{workflow.id}/steps/step-123/uploads/dcc00084-812d-4769-bf77-94518f18ff3d",
         {"filename": "test.csv"},
         content_type="application/json",
         HTTP_AUTHORIZATION="Bearer abc123",
     )
     self.assertEqual(response.status_code, 404)
     self.assertEqual(
         json.loads(response.content)["error"]["code"], "upload-not-found")
コード例 #14
0
 def test_authorization_bearer_token_invalid(self):
     _init_module("x")
     workflow = Workflow.create_and_init()
     workflow.tabs.first().wf_modules.create(
         order=0,
         slug="step-123",
         module_id_name="x",
         file_upload_api_token="abc123",
         params={"file": None},
     )
     response = self.client.post(
         f"/api/v1/workflows/{workflow.id}/steps/step-123/uploads",
         HTTP_AUTHORIZATION="Bearer abc123XXX",
     )
     self.assertEqual(response.status_code, 403)
     self.assertEqual(
         json.loads(response.content)["error"]["code"],
         "authorization-bearer-token-invalid",
     )
コード例 #15
0
    def test_clean_file_happy_path(self):
        workflow = Workflow.create_and_init()
        tab = workflow.tabs.first()
        step = tab.steps.create(module_id_name="uploadfile", order=0, slug="step-1")
        id = str(uuid.uuid4())
        key = f"wf-${workflow.id}/wfm-${step.id}/${id}"
        s3.put_bytes(s3.UserFilesBucket, key, b"1234")
        UploadedFile.objects.create(
            step=step, name="x.csv.gz", size=4, uuid=id, key=key
        )
        with ExitStack() as inner_stack:
            context = self._render_context(step_id=step.id, exit_stack=inner_stack)
            result: Path = clean_value(ParamDType.File(), id, context)
            self.assertIsInstance(result, Path)
            self.assertEqual(result.read_bytes(), b"1234")
            self.assertEqual(result.suffixes, [".csv", ".gz"])

        # Assert that once `exit_stack` goes out of scope, file is deleted
        self.assertFalse(result.exists())
コード例 #16
0
ファイル: test_step.py プロジェクト: lenamax2355/cjworkbench
    def test_set_notifications_to_false(self, log_event):
        user = User.objects.create(username="******", email="*****@*****.**")
        workflow = Workflow.create_and_init(owner=user)
        step = workflow.tabs.first().steps.create(order=0,
                                                  slug="step-1",
                                                  notifications=True)

        response = self.run_handler(
            set_notifications,
            user=user,
            workflow=workflow,
            stepId=step.id,
            notifications=False,
        )
        self.assertResponse(response, data=None)

        step.refresh_from_db()
        self.assertEqual(step.notifications, False)
        log_event.assert_not_called()  # only log if setting to true
コード例 #17
0
 def test_ignore_fresh_lesson(self):
     workflow = Workflow.create_and_init(
         last_viewed_at=(datetime.datetime.now() - FreshTimedelta),
         lesson_slug="analyze-live-twitter",
     )
     tab = workflow.tabs.first()
     step = tab.steps.create(
         order=0,
         slug="step-1",
         module_id_name="fetcher",
         auto_update_data=True,
         next_update=datetime.datetime.now(),
         is_deleted=True,
     )
     with self.assertLogs(lessonautoupdatedisabler.__name__, logging.INFO):
         lessonautoupdatedisabler.disable_stale_auto_update()
     step.refresh_from_db()
     self.assertEqual(step.auto_update_data, True)
     self.assertIsNotNone(step.next_update)
コード例 #18
0
    def setUp(self):
        super().setUp()

        self.queue_render_patcher = patch.object(rabbitmq, "queue_render")
        self.queue_render = self.queue_render_patcher.start()
        self.queue_render.side_effect = async_noop

        self.queue_intercom_message_patcher = patch.object(
            rabbitmq, "queue_intercom_message", async_noop)
        self.queue_intercom_message_patcher.start()

        self.user = create_user("user", "*****@*****.**")

        self.workflow1 = Workflow.create_and_init(name="Workflow 1",
                                                  owner=self.user)
        self.tab1 = self.workflow1.tabs.first()

        # Add another user, with one public and one private workflow
        self.otheruser = create_user("user2", "*****@*****.**")
コード例 #19
0
 def test_complete_json_form_error(self):
     _init_module("x")
     workflow = Workflow.create_and_init()
     wf_module = workflow.tabs.first().wf_modules.create(
         order=0, slug="step-123", module_id_name="x", file_upload_api_token="abc123"
     )
     upload = wf_module.in_progress_uploads.create()
     key = upload.get_upload_key()
     minio.put_bytes(upload.Bucket, key, b"1234567")
     response = self.client.post(
         f"/api/v1/workflows/{workflow.id}/steps/step-123/uploads/{upload.id}",
         {"filename": None},
         content_type="application/json",
         HTTP_AUTHORIZATION="Bearer abc123",
     )
     self.assertEqual(response.status_code, 400)
     error = json.loads(response.content)["error"]
     self.assertEqual(error["code"], "body-has-errors")
     self.assertIn("filename", error["errors"])
コード例 #20
0
    def test_delete_deletes_soft_deleted_step(self):
        workflow = Workflow.create_and_init()
        # Here's a soft-deleted module
        step = workflow.tabs.first().steps.create(order=0,
                                                  slug="step-1",
                                                  module_id_name="foo",
                                                  is_deleted=True)

        self.run_with_async_db(
            commands.do(SetWorkflowTitle,
                        workflow_id=workflow.id,
                        new_value="1"))
        self.run_with_async_db(commands.undo(
            workflow.id))  # fix workflow.last_delta_id
        workflow.deltas.all().delete()
        workflow.delete_orphan_soft_deleted_models()

        with self.assertRaises(Step.DoesNotExist):
            step.refresh_from_db()
コード例 #21
0
    def test_set_stored_data_version_command_set_read(self):
        version = "2018-12-12T21:30:00.000Z"
        user = User.objects.create(username="******", email="*****@*****.**")
        workflow = Workflow.create_and_init(owner=user)
        wf_module = workflow.tabs.first().wf_modules.create(order=0, slug="step-1")
        so = wf_module.stored_objects.create(
            stored_at=isoparse(version), size=0, read=False
        )

        response = self.run_handler(
            set_stored_data_version,
            user=user,
            workflow=workflow,
            wfModuleId=wf_module.id,
            version=version,
        )
        self.assertResponse(response, data=None)
        so.refresh_from_db()
        self.assertEqual(so.read, True)
コード例 #22
0
    def test_delete_protects_non_deleted_step(self):
        workflow = Workflow.create_and_init()
        # Here's a soft-deleted module
        step = workflow.tabs.first().steps.create(order=0,
                                                  slug="step-1",
                                                  module_id_name="foo",
                                                  is_deleted=False)

        # delete a delta
        self.run_with_async_db(
            commands.do(SetWorkflowTitle,
                        workflow_id=workflow.id,
                        new_value="1"))
        self.run_with_async_db(commands.undo(
            workflow.id))  # fix workflow.last_delta_id
        workflow.deltas.all().delete()
        workflow.delete_orphan_soft_deleted_models()

        step.refresh_from_db()  # no DoesNotExist: it's not deleted
コード例 #23
0
    def test_execute_tempdir_not_in_tmpfs(self):
        # /tmp is RAM; /var/tmp is disk. Assert big files go on disk.
        workflow = Workflow.create_and_init()
        tab = workflow.tabs.first()
        delta1 = workflow.last_delta
        create_module_zipfile("mod")
        tab.wf_modules.create(
            order=0,
            slug="step-1",
            last_relevant_delta_id=delta1.id - 1,
            module_id_name="mod",
        )

        with patch.object(Kernel,
                          "render",
                          side_effect=mock_render({"B": [2]})):
            self._execute(workflow)
            self.assertRegex(str(Kernel.render.call_args[1]["basedir"]),
                             r"/var/tmp/")
コード例 #24
0
    def test_redo_modify_last_applied_at(self, websockets_notify):
        websockets_notify.side_effect = async_noop

        date0 = datetime.datetime(2000, 1, 1)
        date1 = datetime.datetime.now()

        with freeze_time(date0):
            workflow = Workflow.create_and_init()
            delta = self.run_with_async_db(
                commands.do(SetWorkflowTitle,
                            workflow_id=workflow.id,
                            new_value="1"))
            self.run_with_async_db(commands.undo(workflow.id))

        with freeze_time(date1):
            self.run_with_async_db(commands.redo(workflow.id))

        delta.refresh_from_db()
        self.assertEqual(delta.last_applied_at, date1)
コード例 #25
0
    def test_delete_custom_report_chart(self, send_update):
        future_none = asyncio.Future()
        future_none.set_result(None)
        send_update.return_value = future_none

        workflow = Workflow.create_and_init(
            selected_tab_position=0, has_custom_report=True
        )  # tab-1
        tab2 = workflow.tabs.create(position=1, slug="tab-2")
        step = tab2.steps.create(
            order=0,
            slug="step-x",
            last_relevant_delta_id=workflow.last_delta_id,
            params={},
        )

        block1 = workflow.blocks.create(
            position=0, slug="block-1", block_type="Text", text_markdown="1"
        )
        block2 = workflow.blocks.create(
            position=1, slug="block-2", block_type="Chart", step_id=step.id
        )
        block3 = workflow.blocks.create(
            position=2, slug="block-3", block_type="Text", text_markdown="3"
        )

        self.run_with_async_db(
            commands.do(DeleteTab, workflow_id=workflow.id, tab=tab2)
        )
        delta1 = send_update.call_args[0][1]
        self.assertEqual(delta1.workflow.block_slugs, ["block-1", "block-3"])
        self.assertEqual(delta1.blocks, {})
        self.assertEqual(delta1.clear_block_slugs, frozenset(["block-2"]))
        with self.assertRaises(Block.DoesNotExist):
            block2.refresh_from_db()
        block3.refresh_from_db()
        self.assertEqual(block3.position, 1)

        self.run_with_async_db(commands.undo(workflow.id))
        delta2 = send_update.call_args[0][1]
        self.assertEqual(delta2.workflow.block_slugs, ["block-1", "block-2", "block-3"])
        self.assertEqual(delta2.blocks, {"block-2": clientside.ChartBlock("step-x")})
        self.assertEqual(delta2.clear_block_slugs, frozenset())
コード例 #26
0
    def test_reorder_modules(self):
        user = User.objects.create(username="******", email="*****@*****.**")
        workflow = Workflow.create_and_init(owner=user)  # tab-1
        tab = workflow.tabs.first()  # tab-1
        step1 = tab.wf_modules.create(order=0, slug="step-1")
        step2 = tab.wf_modules.create(order=1, slug="step-2")

        response = self.run_handler(
            reorder_modules,
            user=user,
            workflow=workflow,
            tabSlug="tab-1",
            wfModuleIds=[step2.id, step1.id],
        )
        self.assertResponse(response, data=None)

        command = ReorderModulesCommand.objects.first()
        self.assertEquals(command.tab_id, tab.id)
        self.assertEquals(command.workflow_id, workflow.id)
コード例 #27
0
 def test_reset_file_upload_api_token(self):
     # Currently, we don't restrict this API to just "upload" modules. We do
     # restrict the actual _uploads_, so this oversight isn't a big deal.
     user = User.objects.create()
     workflow = Workflow.create_and_init(owner=user)
     step = workflow.tabs.first().steps.create(module_id_name="x",
                                               order=0,
                                               slug="step-1")
     response = self.run_handler(
         reset_file_upload_api_token,
         user=user,
         workflow=workflow,
         stepSlug="step-1",
     )
     step.refresh_from_db()
     self.assertEqual(len(step.file_upload_api_token),
                      43)  # 32 bytes, base64-encoded
     self.assertResponse(response,
                         data={"apiToken": step.file_upload_api_token})
コード例 #28
0
    def test_reorder_blocks_on_custom_report(self, send_update):
        future_none = asyncio.Future()
        future_none.set_result(None)
        send_update.return_value = future_none

        workflow = Workflow.create_and_init(has_custom_report=True)
        workflow.blocks.create(position=0,
                               slug="block-1",
                               block_type="Text",
                               text_markdown="1")
        workflow.blocks.create(position=1,
                               slug="block-2",
                               block_type="Text",
                               text_markdown="1")
        workflow.blocks.create(position=2,
                               slug="block-3",
                               block_type="Text",
                               text_markdown="1")

        self.run_with_async_db(
            commands.do(
                ReorderBlocks,
                workflow_id=workflow.id,
                slugs=["block-2", "block-3", "block-1"],
            ))
        self.assertEqual(
            list(workflow.blocks.values_list("slug", "position")),
            [("block-2", 0), ("block-3", 1), ("block-1", 2)],
        )
        delta1 = send_update.call_args[0][1]
        self.assertIsNone(delta1.workflow.has_custom_report)
        self.assertEqual(delta1.workflow.block_slugs,
                         ["block-2", "block-3", "block-1"])

        self.run_with_async_db(commands.undo(workflow.id))
        self.assertEqual(
            list(workflow.blocks.values_list("slug", "position")),
            [("block-1", 0), ("block-2", 1), ("block-3", 2)],
        )
        delta2 = send_update.call_args[0][1]
        self.assertIsNone(delta2.workflow.has_custom_report)
        self.assertEqual(delta2.workflow.block_slugs,
                         ["block-1", "block-2", "block-3"])
コード例 #29
0
    def test_set_collapsed_forces_bool(self):
        user = User.objects.create(username="******", email="*****@*****.**")
        workflow = Workflow.create_and_init(owner=user)
        step = workflow.tabs.first().steps.create(order=0,
                                                  slug="step-1",
                                                  is_collapsed=False)

        # bool('False') is true
        response = self.run_handler(
            set_collapsed,
            user=user,
            workflow=workflow,
            stepId=step.id,
            isCollapsed="False",
        )
        self.assertResponse(response, data=None)

        step.refresh_from_db()
        self.assertEqual(step.is_collapsed, True)
コード例 #30
0
 def test_fetch_integration_tempfiles_are_on_disk(self, create_result):
     # /tmp is RAM; /var/tmp is disk. Assert big files go on disk.
     workflow = Workflow.create_and_init()
     create_module_zipfile(
         "mod",
         python_code=
         ("import pandas as pd\ndef fetch(params): return pd.DataFrame({'A': [1]})\ndef render(table, params): return table"
          ),
     )
     wf_module = workflow.tabs.first().wf_modules.create(
         order=0, slug="step-1", module_id_name="mod")
     with self.assertLogs(level=logging.INFO):
         cjwstate.modules.init_module_system()
         self.run_with_async_db(
             fetch.fetch(workflow_id=workflow.id,
                         wf_module_id=wf_module.id))
     create_result.assert_called()
     saved_result: FetchResult = create_result.call_args[0][2]
     self.assertRegex(str(saved_result.path), r"/var/tmp/")