canvas 0.17.0__py3-none-any.whl → 0.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of canvas might be problematic. Click here for more details.
- {canvas-0.17.0.dist-info → canvas-0.19.0.dist-info}/METADATA +1 -1
- {canvas-0.17.0.dist-info → canvas-0.19.0.dist-info}/RECORD +35 -21
- canvas_cli/apps/plugin/plugin.py +4 -0
- canvas_cli/utils/validators/manifest_schema.py +12 -0
- canvas_generated/messages/events_pb2.py +2 -2
- canvas_generated/messages/events_pb2.pyi +88 -0
- canvas_sdk/commands/commands/reason_for_visit.py +18 -3
- canvas_sdk/commands/tests/test_utils.py +15 -3
- canvas_sdk/commands/tests/unit/tests.py +7 -16
- canvas_sdk/effects/surescripts/__init__.py +11 -0
- canvas_sdk/effects/task/__init__.py +3 -0
- canvas_sdk/effects/task/task.py +3 -0
- canvas_sdk/questionnaires/__init__.py +3 -0
- canvas_sdk/questionnaires/tests/__init__.py +0 -0
- canvas_sdk/questionnaires/tests/test_utils.py +74 -0
- canvas_sdk/questionnaires/utils.py +117 -0
- canvas_sdk/templates/utils.py +7 -12
- canvas_sdk/utils/__init__.py +8 -2
- canvas_sdk/utils/http.py +112 -2
- canvas_sdk/utils/plugins.py +25 -0
- canvas_sdk/v1/data/__init__.py +4 -1
- canvas_sdk/v1/data/billing.py +29 -2
- canvas_sdk/v1/data/coverage.py +1 -1
- canvas_sdk/v1/data/reason_for_visit.py +22 -0
- canvas_sdk/v1/data/team.py +76 -0
- plugin_runner/sandbox.py +6 -6
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/CANVAS_MANIFEST.json +52 -0
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/README.md +11 -0
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/my_protocol.py +39 -0
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/questionnaires/example_questionnaire.yml +61 -0
- plugin_runner/tests/test_plugin_runner.py +12 -12
- protobufs/canvas_generated/messages/events.proto +44 -36
- {canvas-0.17.0.dist-info → canvas-0.19.0.dist-info}/WHEEL +0 -0
- {canvas-0.17.0.dist-info → canvas-0.19.0.dist-info}/entry_points.txt +0 -0
canvas_sdk/v1/data/billing.py
CHANGED
|
@@ -44,10 +44,16 @@ class BillingLineItem(models.Model):
|
|
|
44
44
|
created = models.DateTimeField()
|
|
45
45
|
modified = models.DateTimeField()
|
|
46
46
|
note = models.ForeignKey(
|
|
47
|
-
"v1.Note",
|
|
47
|
+
"v1.Note",
|
|
48
|
+
on_delete=models.DO_NOTHING,
|
|
49
|
+
related_name="billing_line_items",
|
|
50
|
+
null=True,
|
|
48
51
|
)
|
|
49
52
|
patient = models.ForeignKey(
|
|
50
|
-
"v1.Patient",
|
|
53
|
+
"v1.Patient",
|
|
54
|
+
on_delete=models.DO_NOTHING,
|
|
55
|
+
related_name="billing_line_items",
|
|
56
|
+
null=True,
|
|
51
57
|
)
|
|
52
58
|
cpt = models.CharField()
|
|
53
59
|
charge = models.DecimalField()
|
|
@@ -56,3 +62,24 @@ class BillingLineItem(models.Model):
|
|
|
56
62
|
command_type = models.CharField()
|
|
57
63
|
command_id = models.IntegerField()
|
|
58
64
|
status = models.CharField(choices=BillingLineItemStatus.choices)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class BillingLineItemModifier(models.Model):
|
|
68
|
+
"""BillingLineItemModifier."""
|
|
69
|
+
|
|
70
|
+
class Meta:
|
|
71
|
+
managed = False
|
|
72
|
+
db_table = "canvas_sdk_data_api_billinglineitemmodifier_001"
|
|
73
|
+
|
|
74
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
75
|
+
system = models.CharField()
|
|
76
|
+
version = models.CharField()
|
|
77
|
+
code = models.CharField()
|
|
78
|
+
display = models.CharField()
|
|
79
|
+
user_selected = models.BooleanField()
|
|
80
|
+
line_item = models.ForeignKey(
|
|
81
|
+
"v1.BillingLineItem",
|
|
82
|
+
on_delete=models.DO_NOTHING,
|
|
83
|
+
related_name="modifiers",
|
|
84
|
+
null=True,
|
|
85
|
+
)
|
canvas_sdk/v1/data/coverage.py
CHANGED
|
@@ -46,7 +46,7 @@ class CoverageRelationshipCode(models.TextChoices):
|
|
|
46
46
|
"""CoverageRelationshipCode."""
|
|
47
47
|
|
|
48
48
|
SELF = "18", "Self"
|
|
49
|
-
SPOUSE = "01" "Spouse"
|
|
49
|
+
SPOUSE = "01", "Spouse"
|
|
50
50
|
CHILD_INSURED_HAS_FINANCIAL_RESP = "19", "Natural Child, insured has financial responsibility"
|
|
51
51
|
CHILD_HAS_FINANCIAL_RESP = "43", "Natural Child, insured does not have financial responsibility"
|
|
52
52
|
STEP_CHILD = "17", "Step Child"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.contrib.postgres.fields import ArrayField
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ReasonForVisitSettingCoding(models.Model):
|
|
6
|
+
"""ReasonForVisitSettingCoding."""
|
|
7
|
+
|
|
8
|
+
class Meta:
|
|
9
|
+
managed = False
|
|
10
|
+
db_table = "canvas_sdk_data_api_reasonforvisitsettingcoding_001"
|
|
11
|
+
|
|
12
|
+
objects: models.Manager["ReasonForVisitSettingCoding"]
|
|
13
|
+
|
|
14
|
+
id = models.UUIDField()
|
|
15
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
16
|
+
|
|
17
|
+
code = models.CharField()
|
|
18
|
+
display = models.CharField()
|
|
19
|
+
system = models.CharField()
|
|
20
|
+
version = models.CharField()
|
|
21
|
+
|
|
22
|
+
duration = ArrayField(models.DurationField())
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from django.contrib.postgres.fields import ArrayField
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
4
|
+
from canvas_sdk.v1.data.common import ContactPointState, ContactPointSystem, ContactPointUse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TeamResponsibility(models.TextChoices):
|
|
8
|
+
"""TeamResponsibility."""
|
|
9
|
+
|
|
10
|
+
COLLECT_SPECIMENS_FROM_PATIENT = (
|
|
11
|
+
"COLLECT_SPECIMENS_FROM_PATIENT",
|
|
12
|
+
"Collect specimens from a patient",
|
|
13
|
+
)
|
|
14
|
+
COMMUNICATE_DIAGNOSTIC_RESULTS_TO_PATIENT = (
|
|
15
|
+
"COMMUNICATE_DIAGNOSTIC_RESULTS_TO_PATIENT",
|
|
16
|
+
"Communicate diagnostic results to patient",
|
|
17
|
+
)
|
|
18
|
+
COORDINATE_REFERRALS_FOR_PATIENT = (
|
|
19
|
+
"COORDINATE_REFERRALS_FOR_PATIENT",
|
|
20
|
+
"Coordinate referrals for a patient",
|
|
21
|
+
)
|
|
22
|
+
PROCESS_REFILL_REQUESTS = "PROCESS_REFILL_REQUESTS", "Process refill requests from a pharmacy"
|
|
23
|
+
PROCESS_CHANGE_REQUESTS = "PROCESS_CHANGE_REQUESTS", "Process change requests from a pharmacy"
|
|
24
|
+
SCHEDULE_LAB_VISITS_FOR_PATIENT = (
|
|
25
|
+
"SCHEDULE_LAB_VISITS_FOR_PATIENT",
|
|
26
|
+
"Schedule lab visits for a patient",
|
|
27
|
+
)
|
|
28
|
+
POPULATION_HEALTH_CAMPAIGN_OUTREACH = (
|
|
29
|
+
"POPULATION_HEALTH_CAMPAIGN_OUTREACH",
|
|
30
|
+
"Population health campaign outreach",
|
|
31
|
+
)
|
|
32
|
+
COLLECT_PATIENT_PAYMENTS = "COLLECT_PATIENT_PAYMENTS", "Collect patient payments"
|
|
33
|
+
COMPLETE_OPEN_LAB_ORDERS = "COMPLETE_OPEN_LAB_ORDERS", "Complete open lab orders"
|
|
34
|
+
REVIEW_ERA_POSTING_EXCEPTIONS = (
|
|
35
|
+
"REVIEW_ERA_POSTING_EXCEPTIONS",
|
|
36
|
+
"Review electronic remittance posting exceptions",
|
|
37
|
+
)
|
|
38
|
+
REVIEW_COVERAGES = "REVIEW_COVERAGES", "Review incomplete patient coverages"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Team(models.Model):
|
|
42
|
+
"""Team."""
|
|
43
|
+
|
|
44
|
+
class Meta:
|
|
45
|
+
managed = False
|
|
46
|
+
db_table = "canvas_sdk_data_api_team_001"
|
|
47
|
+
|
|
48
|
+
id = models.UUIDField()
|
|
49
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
50
|
+
created = models.DateTimeField()
|
|
51
|
+
modified = models.DateTimeField()
|
|
52
|
+
name = models.CharField()
|
|
53
|
+
responsibilities = ArrayField(models.CharField(choices=TeamResponsibility.choices))
|
|
54
|
+
members = models.ManyToManyField( # type: ignore[var-annotated]
|
|
55
|
+
"v1.Staff", # type: ignore[misc]
|
|
56
|
+
related_name="teams",
|
|
57
|
+
db_table="canvas_sdk_data_api_team_members_001",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TeamContactPoint(models.Model):
|
|
62
|
+
"""TeamContactPoint."""
|
|
63
|
+
|
|
64
|
+
class Meta:
|
|
65
|
+
managed = False
|
|
66
|
+
db_table = "canvas_sdk_data_api_teamcontactpoint_001"
|
|
67
|
+
|
|
68
|
+
id = models.UUIDField()
|
|
69
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
70
|
+
system = models.CharField(choices=ContactPointSystem.choices)
|
|
71
|
+
value = models.CharField()
|
|
72
|
+
use = models.CharField(choices=ContactPointUse.choices)
|
|
73
|
+
use_notes = models.CharField()
|
|
74
|
+
rank = models.IntegerField()
|
|
75
|
+
state = models.CharField(choices=ContactPointState.choices)
|
|
76
|
+
team = models.ForeignKey(Team, on_delete=models.DO_NOTHING, related_name="telecom")
|
plugin_runner/sandbox.py
CHANGED
|
@@ -45,6 +45,7 @@ ALLOWED_MODULES = frozenset(
|
|
|
45
45
|
"canvas_sdk.events",
|
|
46
46
|
"canvas_sdk.handlers",
|
|
47
47
|
"canvas_sdk.protocols",
|
|
48
|
+
"canvas_sdk.questionnaires",
|
|
48
49
|
"canvas_sdk.utils",
|
|
49
50
|
"canvas_sdk.templates",
|
|
50
51
|
"canvas_sdk.v1",
|
|
@@ -173,12 +174,12 @@ class Sandbox:
|
|
|
173
174
|
):
|
|
174
175
|
self.warn(
|
|
175
176
|
node,
|
|
176
|
-
f'"{name}" is an invalid variable name because it
|
|
177
|
+
f'"{name}" is an invalid variable name because it starts with "_"',
|
|
177
178
|
)
|
|
178
179
|
elif name.endswith("__roles__"):
|
|
179
180
|
self.error(
|
|
180
181
|
node,
|
|
181
|
-
f'"{name}" is an invalid variable name because
|
|
182
|
+
f'"{name}" is an invalid variable name because it ends with "__roles__".',
|
|
182
183
|
)
|
|
183
184
|
elif name in FORBIDDEN_FUNC_NAMES:
|
|
184
185
|
self.error(node, f'"{name}" is a reserved name.')
|
|
@@ -215,21 +216,20 @@ class Sandbox:
|
|
|
215
216
|
if node.attr.startswith("_") and node.attr != "_":
|
|
216
217
|
self.warn(
|
|
217
218
|
node,
|
|
218
|
-
f'"{node.attr}" is an invalid attribute name because it starts
|
|
219
|
+
f'"{node.attr}" is an invalid attribute name because it starts with "_".',
|
|
219
220
|
)
|
|
220
221
|
|
|
221
222
|
if node.attr.endswith("__roles__"):
|
|
222
223
|
self.error(
|
|
223
224
|
node,
|
|
224
|
-
f'"{node.attr}" is an invalid attribute name because it ends '
|
|
225
|
-
'with "__roles__".',
|
|
225
|
+
f'"{node.attr}" is an invalid attribute name because it ends with "__roles__".',
|
|
226
226
|
)
|
|
227
227
|
|
|
228
228
|
if isinstance(node.ctx, ast.Load):
|
|
229
229
|
node = self.node_contents_visit(node)
|
|
230
230
|
new_node = ast.Call(
|
|
231
231
|
func=ast.Name("_getattr_", ast.Load()),
|
|
232
|
-
args=[node.value, ast.
|
|
232
|
+
args=[node.value, ast.Constant(node.attr)],
|
|
233
233
|
keywords=[],
|
|
234
234
|
)
|
|
235
235
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sdk_version": "0.1.4",
|
|
3
|
+
"plugin_version": "0.0.1",
|
|
4
|
+
"name": "test_load_questionnaire",
|
|
5
|
+
"description": "Edit the description in CANVAS_MANIFEST.json",
|
|
6
|
+
"components": {
|
|
7
|
+
"protocols": [
|
|
8
|
+
{
|
|
9
|
+
"class": "test_load_questionnaire.protocols.my_protocol:ValidQuestionnaire",
|
|
10
|
+
"description": "A protocol that does xyz...",
|
|
11
|
+
"data_access": {
|
|
12
|
+
"event": "",
|
|
13
|
+
"read": [],
|
|
14
|
+
"write": []
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"class": "test_load_questionnaire.protocols.my_protocol:InvalidQuestionnaire",
|
|
19
|
+
"description": "A protocol that does xyz...",
|
|
20
|
+
"data_access": {
|
|
21
|
+
"event": "",
|
|
22
|
+
"read": [],
|
|
23
|
+
"write": []
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"class": "test_load_questionnaire.protocols.my_protocol:ForbiddenQuestionnaire",
|
|
28
|
+
"description": "A protocol that does xyz...",
|
|
29
|
+
"data_access": {
|
|
30
|
+
"event": "",
|
|
31
|
+
"read": [],
|
|
32
|
+
"write": []
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"commands": [],
|
|
37
|
+
"content": [],
|
|
38
|
+
"effects": [],
|
|
39
|
+
"views": [],
|
|
40
|
+
"questionnaires": [
|
|
41
|
+
{
|
|
42
|
+
"template": "questionnaires/example_questionnaire.yml"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"secrets": [],
|
|
47
|
+
"tags": {},
|
|
48
|
+
"references": [],
|
|
49
|
+
"license": "",
|
|
50
|
+
"diagram": false,
|
|
51
|
+
"readme": "./README.md"
|
|
52
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
test_load_questionnaire
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
## Description
|
|
5
|
+
|
|
6
|
+
A description of this plugin
|
|
7
|
+
|
|
8
|
+
### Important Note!
|
|
9
|
+
|
|
10
|
+
The CANVAS_MANIFEST.json is used when installing your plugin. Please ensure it
|
|
11
|
+
gets updated if you add, remove, or rename protocols.
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from canvas_sdk.effects import Effect
|
|
4
|
+
from canvas_sdk.events import EventType
|
|
5
|
+
from canvas_sdk.handlers import BaseHandler
|
|
6
|
+
from canvas_sdk.questionnaires import questionnaire_from_yaml
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ValidQuestionnaire(BaseHandler):
|
|
10
|
+
"""You should put a helpful description of this protocol's behavior here."""
|
|
11
|
+
|
|
12
|
+
RESPONDS_TO = [EventType.Name(EventType.UNKNOWN)]
|
|
13
|
+
|
|
14
|
+
def compute(self) -> list[Effect]:
|
|
15
|
+
"""This method gets called when an event of the type RESPONDS_TO is fired."""
|
|
16
|
+
config = questionnaire_from_yaml("questionnaires/example_questionnaire.yml")
|
|
17
|
+
return [Effect(payload=json.dumps(config))]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class InvalidQuestionnaire(BaseHandler):
|
|
21
|
+
"""You should put a helpful description of this protocol's behavior here."""
|
|
22
|
+
|
|
23
|
+
RESPONDS_TO = [EventType.Name(EventType.UNKNOWN)]
|
|
24
|
+
|
|
25
|
+
def compute(self) -> list[Effect]:
|
|
26
|
+
"""This method gets called when an event of the type RESPONDS_TO is fired."""
|
|
27
|
+
questionnaire_from_yaml("questionnaires/example_questionnaire1.yml")
|
|
28
|
+
return []
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ForbiddenQuestionnaire(BaseHandler):
|
|
32
|
+
"""You should put a helpful description of this protocol's behavior here."""
|
|
33
|
+
|
|
34
|
+
RESPONDS_TO = [EventType.Name(EventType.UNKNOWN)]
|
|
35
|
+
|
|
36
|
+
def compute(self) -> list[Effect]:
|
|
37
|
+
"""This method gets called when an event of the type RESPONDS_TO is fired."""
|
|
38
|
+
questionnaire_from_yaml("../../questionnaires/example_questionnaire.yml")
|
|
39
|
+
return []
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../../../../schemas/questionnaire.json
|
|
2
|
+
|
|
3
|
+
name: Example Name
|
|
4
|
+
form_type: QUES
|
|
5
|
+
code_system: LOINC
|
|
6
|
+
code: QUES_EXAMPLE_NAME
|
|
7
|
+
can_originate_in_charting: true
|
|
8
|
+
prologue: This is an example of a structured assessment with single select, multiselect, and free text responses.
|
|
9
|
+
questions:
|
|
10
|
+
- content: "This is question #1"
|
|
11
|
+
code_system: CPT
|
|
12
|
+
code: H0005
|
|
13
|
+
code_description: ""
|
|
14
|
+
responses_code_system: INTERNAL
|
|
15
|
+
responses_type: SING
|
|
16
|
+
display_result_in_social_history_section: true
|
|
17
|
+
responses:
|
|
18
|
+
- name: "Single select response #1"
|
|
19
|
+
code: QUES_EXAMPLE_NAME_Q1_A1
|
|
20
|
+
code_description: ''
|
|
21
|
+
value: "1"
|
|
22
|
+
- name: "Single select response #2"
|
|
23
|
+
code: QUES_EXAMPLE_NAME_Q1_A2
|
|
24
|
+
code_description: ''
|
|
25
|
+
value: "0"
|
|
26
|
+
- name: "Single select response #3"
|
|
27
|
+
code: QUES_EXAMPLE_NAME_Q1_A3
|
|
28
|
+
code_description: ''
|
|
29
|
+
value: "0"
|
|
30
|
+
- content: "This is question #2"
|
|
31
|
+
code_system: INTERNAL
|
|
32
|
+
code: QUES_EXAMPLE_NAME_Q2
|
|
33
|
+
code_description: ""
|
|
34
|
+
responses_code_system: ICD-10
|
|
35
|
+
responses_type: MULT
|
|
36
|
+
display_result_in_social_history_section: true
|
|
37
|
+
responses:
|
|
38
|
+
- name: "Multi select response #1"
|
|
39
|
+
code: F1910
|
|
40
|
+
code_description: ''
|
|
41
|
+
value: "0"
|
|
42
|
+
- name: "Multi select response #2"
|
|
43
|
+
code: QUES_EXAMPLE_NAME_Q1_A1
|
|
44
|
+
code_description: ''
|
|
45
|
+
value: "2"
|
|
46
|
+
- name: "Multi select response #3"
|
|
47
|
+
code: QUES_EXAMPLE_NAME_Q1_A2
|
|
48
|
+
code_description: ''
|
|
49
|
+
value: "0"
|
|
50
|
+
- content: "This is question #3"
|
|
51
|
+
code_system: INTERNAL
|
|
52
|
+
code: QUES_EXAMPLE_NAME_Q3
|
|
53
|
+
code_description: ""
|
|
54
|
+
responses_code_system: INTERNAL
|
|
55
|
+
responses_type: TXT
|
|
56
|
+
display_result_in_social_history_section: true
|
|
57
|
+
responses:
|
|
58
|
+
- name: "Free text response"
|
|
59
|
+
code: QUES_EXAMPLE_NAME_Q3_A1
|
|
60
|
+
code_description: ''
|
|
61
|
+
value: "This is a default pre-populated free text response."
|
|
@@ -83,9 +83,9 @@ def test_load_plugins_with_plugin_that_imports_other_modules_outside_plugin_pack
|
|
|
83
83
|
with caplog.at_level(logging.ERROR):
|
|
84
84
|
load_or_reload_plugin(install_test_plugin)
|
|
85
85
|
|
|
86
|
-
assert any(
|
|
87
|
-
"
|
|
88
|
-
)
|
|
86
|
+
assert any("Error importing module" in record.message for record in caplog.records), (
|
|
87
|
+
"log.error() was not called with the expected message."
|
|
88
|
+
)
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
@pytest.mark.parametrize(
|
|
@@ -102,9 +102,9 @@ def test_load_plugins_with_plugin_that_imports_forbidden_modules(
|
|
|
102
102
|
with caplog.at_level(logging.ERROR):
|
|
103
103
|
load_or_reload_plugin(install_test_plugin)
|
|
104
104
|
|
|
105
|
-
assert any(
|
|
106
|
-
"
|
|
107
|
-
)
|
|
105
|
+
assert any("Error importing module" in record.message for record in caplog.records), (
|
|
106
|
+
"log.error() was not called with the expected message."
|
|
107
|
+
)
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
@pytest.mark.parametrize(
|
|
@@ -144,9 +144,9 @@ def test_plugin_that_implicitly_imports_allowed_modules(
|
|
|
144
144
|
]["class"]
|
|
145
145
|
class_handler(Event(EventRequest(type=EventType.UNKNOWN))).compute()
|
|
146
146
|
|
|
147
|
-
assert any(
|
|
148
|
-
"
|
|
149
|
-
)
|
|
147
|
+
assert any("Hello, World!" in record.message for record in caplog.records), (
|
|
148
|
+
"log.info() with Template.render() was not called."
|
|
149
|
+
)
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
@pytest.mark.parametrize(
|
|
@@ -170,9 +170,9 @@ def test_plugin_that_implicitly_imports_forbidden_modules(
|
|
|
170
170
|
]["class"]
|
|
171
171
|
class_handler(Event(EventRequest(type=EventType.UNKNOWN))).compute()
|
|
172
172
|
|
|
173
|
-
assert (
|
|
174
|
-
|
|
175
|
-
)
|
|
173
|
+
assert any("os list dir" in record.message for record in caplog.records) is False, (
|
|
174
|
+
"log.info() with os.listdir() was called."
|
|
175
|
+
)
|
|
176
176
|
|
|
177
177
|
|
|
178
178
|
@pytest.mark.parametrize("install_test_plugin", ["example_plugin"], indirect=True)
|
|
@@ -218,18 +218,20 @@ enum EventType {
|
|
|
218
218
|
ASSESS__CONDITION__POST_SEARCH = 7012;
|
|
219
219
|
ASSESS__CONDITION__PRE_SEARCH = 7013;
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
221
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_ORIGINATE = 8000;
|
|
222
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_ORIGINATE = 8001;
|
|
223
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_UPDATE = 8002;
|
|
224
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_UPDATE = 8003;
|
|
225
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_COMMIT = 8004;
|
|
226
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_COMMIT = 8005;
|
|
227
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_DELETE = 8006;
|
|
228
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_DELETE = 8007;
|
|
229
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_ENTER_IN_ERROR = 8008;
|
|
230
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_ENTER_IN_ERROR = 8009;
|
|
231
|
+
CANCEL_PRESCRIPTION_COMMAND__PRE_EXECUTE_ACTION = 8010;
|
|
232
|
+
CANCEL_PRESCRIPTION_COMMAND__POST_EXECUTE_ACTION = 8011;
|
|
233
|
+
CANCEL_PRESCRIPTION__SELECTED_PRESCRIPTION__PRE_SEARCH = 8012;
|
|
234
|
+
CANCEL_PRESCRIPTION__SELECTED_PRESCRIPTION__POST_SEARCH = 8013;
|
|
233
235
|
|
|
234
236
|
// CHART_SECTION_REVIEW_COMMAND__PRE_ORIGINATE = 9000;
|
|
235
237
|
// CHART_SECTION_REVIEW_COMMAND__POST_ORIGINATE = 9001;
|
|
@@ -782,18 +784,20 @@ enum EventType {
|
|
|
782
784
|
ROS__QUESTIONNAIRE__POST_SEARCH = 42013;
|
|
783
785
|
|
|
784
786
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
787
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_ORIGINATE = 43000;
|
|
788
|
+
SNOOZE_PROTOCOL_COMMAND__POST_ORIGINATE = 43001;
|
|
789
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_UPDATE = 43002;
|
|
790
|
+
SNOOZE_PROTOCOL_COMMAND__POST_UPDATE = 43003;
|
|
791
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_COMMIT = 43004;
|
|
792
|
+
SNOOZE_PROTOCOL_COMMAND__POST_COMMIT = 43005;
|
|
793
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_DELETE = 43006;
|
|
794
|
+
SNOOZE_PROTOCOL_COMMAND__POST_DELETE = 43007;
|
|
795
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_ENTER_IN_ERROR = 43008;
|
|
796
|
+
SNOOZE_PROTOCOL_COMMAND__POST_ENTER_IN_ERROR = 43009;
|
|
797
|
+
SNOOZE_PROTOCOL_COMMAND__PRE_EXECUTE_ACTION = 43010;
|
|
798
|
+
SNOOZE_PROTOCOL_COMMAND__POST_EXECUTE_ACTION = 43011;
|
|
799
|
+
SNOOZE_PROTOCOL__PROTOCOL__PRE_SEARCH = 43012;
|
|
800
|
+
SNOOZE_PROTOCOL__PROTOCOL__POST_SEARCH = 43013;
|
|
797
801
|
|
|
798
802
|
STOP_MEDICATION_COMMAND__PRE_ORIGINATE = 44000;
|
|
799
803
|
STOP_MEDICATION_COMMAND__POST_ORIGINATE = 44001;
|
|
@@ -874,18 +878,22 @@ enum EventType {
|
|
|
874
878
|
// UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND__PRE_EXECUTE_ACTION = 48010;
|
|
875
879
|
// UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND__POST_EXECUTE_ACTION = 48011;
|
|
876
880
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
881
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_ORIGINATE = 49000;
|
|
882
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_ORIGINATE = 49001;
|
|
883
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_UPDATE = 49002;
|
|
884
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_UPDATE = 49003;
|
|
885
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_COMMIT = 49004;
|
|
886
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_COMMIT = 49005;
|
|
887
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_DELETE = 49006;
|
|
888
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_DELETE = 49007;
|
|
889
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_ENTER_IN_ERROR = 49008;
|
|
890
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_ENTER_IN_ERROR = 49009;
|
|
891
|
+
UPDATE_DIAGNOSIS_COMMAND__PRE_EXECUTE_ACTION = 49010;
|
|
892
|
+
UPDATE_DIAGNOSIS_COMMAND__POST_EXECUTE_ACTION = 49011;
|
|
893
|
+
UPDATE_DIAGNOSIS__CONDITION__PRE_SEARCH = 49012;
|
|
894
|
+
UPDATE_DIAGNOSIS__CONDITION__POST_SEARCH = 49013;
|
|
895
|
+
UPDATE_DIAGNOSIS__NEW_CONDITION__PRE_SEARCH = 49014;
|
|
896
|
+
UPDATE_DIAGNOSIS__NEW_CONDITION__POST_SEARCH = 49015;
|
|
889
897
|
|
|
890
898
|
UPDATE_GOAL_COMMAND__PRE_ORIGINATE = 50000;
|
|
891
899
|
UPDATE_GOAL_COMMAND__POST_ORIGINATE = 50001;
|
|
File without changes
|
|
File without changes
|