22Mixin for testing transformers for all of the currently supported events
33"""
44import json
5+ import logging
56import os
67from abc import abstractmethod
78from unittest .mock import patch
1617from event_routing_backends .processors .mixins .base_transformer import BaseTransformerMixin
1718from event_routing_backends .tests .factories import UserFactory
1819
20+ logger = logging .getLogger (__name__ )
1921User = get_user_model ()
2022
2123TEST_DIR_PATH = os .path .dirname (os .path .abspath (__file__ ))
2224
23- EVENT_FIXTURE_FILENAMES = [
24- event_file_name for event_file_name in os .listdir (
25- f'{ TEST_DIR_PATH } /fixtures/current/'
26- ) if event_file_name .endswith (".json" )
27- ]
25+ try :
26+ EVENT_FIXTURE_FILENAMES = [
27+ event_file_name for event_file_name in os .listdir (
28+ f'{ TEST_DIR_PATH } /fixtures/current/'
29+ ) if event_file_name .endswith (".json" )
30+ ]
31+
32+ except FileNotFoundError as exc : # pragma: no cover
33+ # This exception may happen when these test mixins are used outside of the ERB package.
34+ logger .exception (exc )
35+ EVENT_FIXTURE_FILENAMES = []
2836
2937
3038class DummyTransformer (BaseTransformerMixin ):
3139 required_fields = ('does_not_exist' ,)
3240
3341
34- @ddt .ddt
35- class TransformersTestMixin :
42+ class TransformersFixturesTestMixin :
3643 """
37- Test that supported events are transformed correctly .
44+ Mixin to help test event transforms using "raw" and "expected" fixture data .
3845 """
3946 # no limit to diff in the output of tests
4047 maxDiff = None
4148
4249 registry = None
43- EXCEPTED_EVENTS_FIXTURES_PATH = None
4450
4551 def setUp (self ):
52+ super ().setUp ()
4653 UserFactory .
create (
username = 'edx' ,
email = '[email protected] ' )
4754
55+ @property
56+ def raw_events_fixture_path (self ):
57+ """
58+ Return the path to the raw events fixture files.
59+ """
60+ return f"{ TEST_DIR_PATH } /fixtures/current"
61+
62+ @property
63+ def expected_events_fixture_path (self ):
64+ """
65+ Return the path to the expected transformed events fixture files.
66+ """
67+ raise NotImplementedError
68+
4869 def get_raw_event (self , event_filename ):
4970 """
5071 Return raw event json parsed from current fixtures
5172 """
73+ base_event_filename = os .path .basename (event_filename )
5274
53- input_event_file_path = '{test_dir}/fixtures/current/ {event_filename}' .format (
54- test_dir = TEST_DIR_PATH , event_filename = event_filename
75+ input_event_file_path = '{test_dir}/{event_filename}' .format (
76+ test_dir = self . raw_events_fixture_path , event_filename = base_event_filename
5577 )
5678 with open (input_event_file_path , encoding = 'utf-8' ) as current :
5779 data = json .loads (current .read ())
5880 return data
5981
60- @override_settings (RUNNING_WITH_TEST_SETTINGS = True )
61- def test_transformer_version_with_test_settings (self ):
62- self .registry .register ('test_event' )(DummyTransformer )
63- raw_event = self .get_raw_event ('edx.course.enrollment.activated.json' )
64- transformed_event = self .registry .get_transformer (raw_event ).transform ()
65- self .
assert_correct_transformer_version (
transformed_event ,
'[email protected] ' )
66-
67- @override_settings (RUNNING_WITH_TEST_SETTINGS = False )
68- def test_transformer_version (self ):
69- self .registry .register ('test_event' )(DummyTransformer )
70- raw_event = self .get_raw_event ('edx.course.enrollment.activated.json' )
71- transformed_event = self .registry .get_transformer (raw_event ).transform ()
72- self .assert_correct_transformer_version (transformed_event , 'event-routing-backends@{}' .format (__version__ ))
73-
74- def test_with_no_field_transformer (self ):
75- self .registry .register ('test_event' )(DummyTransformer )
76- with self .assertRaises (ValueError ):
77- self .registry .get_transformer ({
78- 'name' : 'test_event'
79- }).transform ()
80-
81- def test_required_field_transformer (self ):
82- self .registry .register ('test_event' )(DummyTransformer )
83- with self .assertRaises (ValueError ):
84- self .registry .get_transformer ({
85- "name" : "edx.course.enrollment.activated"
86- }).transform ()
87-
8882 @abstractmethod
8983 def compare_events (self , transformed_event , expected_event ):
9084 """
9185 Every transformer's test case will implement its own logic to test
9286 events transformation
9387 """
94- @patch ('event_routing_backends.helpers.uuid.uuid4' )
95- @ddt .data (* EVENT_FIXTURE_FILENAMES )
96- def test_event_transformer (self , event_filename , mocked_uuid4 ):
97- # Used to generate the anonymized actor.name,
98- # which in turn is used to generate the event UUID.
99- mocked_uuid4 .return_value = UUID ('32e08e30-f8ae-4ce2-94a8-c2bfe38a70cb' )
88+ raise NotImplementedError
10089
101- # if an event's expected fixture doesn't exist, the test shouldn't fail.
102- # evaluate transformation of only supported event fixtures.
103- expected_event_file_path = '{expected_events_fixtures_path}/{event_filename}' .format (
104- expected_events_fixtures_path = self .EXCEPTED_EVENTS_FIXTURES_PATH , event_filename = event_filename
105- )
90+ def check_event_transformer (self , raw_event_file , expected_event_file ):
91+ """
92+ Test that given event is transformed correctly.
10693
107- if not os .path .isfile (expected_event_file_path ):
108- return
94+ Transforms the contents of `raw_event_file` and compare it against the contents of `expected_event_file`.
10995
110- original_event = self .get_raw_event (event_filename )
111- with open (expected_event_file_path , encoding = 'utf-8' ) as expected :
96+ Writes errors to test_out/ for analysis.
97+ """
98+ original_event = self .get_raw_event (raw_event_file )
99+ with open (expected_event_file , encoding = 'utf-8' ) as expected :
112100 expected_event = json .loads (expected .read ())
113101
102+ event_filename = os .path .basename (raw_event_file )
114103 if "anonymous" in event_filename :
115104 with pytest .raises (ValueError ):
116105 self .registry .get_transformer (original_event ).transform ()
@@ -132,7 +121,61 @@ def test_event_transformer(self, event_filename, mocked_uuid4):
132121 actual_transformed_event_file .write ("," .join (out_events ))
133122 actual_transformed_event_file .write ("]" )
134123
135- with open (f"test_output/expected.{ event_filename } .json" , "w" ) as expected_event_file :
136- json .dump (expected_event , expected_event_file , indent = 4 )
124+ with open (f"test_output/expected.{ raw_event_file } .json" , "w" ) as test_output_file :
125+ json .dump (expected_event , test_output_file , indent = 4 )
137126
138127 raise e
128+
129+
130+ @ddt .ddt
131+ class TransformersTestMixin :
132+ """
133+ Tests that supported events are transformed correctly.
134+ """
135+ def test_with_no_field_transformer (self ):
136+ self .registry .register ('test_event' )(DummyTransformer )
137+ with self .assertRaises (ValueError ):
138+ self .registry .get_transformer ({
139+ 'name' : 'test_event'
140+ }).transform ()
141+
142+ def test_required_field_transformer (self ):
143+ self .registry .register ('test_event' )(DummyTransformer )
144+ with self .assertRaises (ValueError ):
145+ self .registry .get_transformer ({
146+ "name" : "edx.course.enrollment.activated"
147+ }).transform ()
148+
149+ @override_settings (RUNNING_WITH_TEST_SETTINGS = True )
150+ def test_transformer_version_with_test_settings (self ):
151+ self .registry .register ('test_event' )(DummyTransformer )
152+ raw_event = self .get_raw_event ('edx.course.enrollment.activated.json' )
153+ transformed_event = self .registry .get_transformer (raw_event ).transform ()
154+ self .
assert_correct_transformer_version (
transformed_event ,
'[email protected] ' )
155+
156+ @override_settings (RUNNING_WITH_TEST_SETTINGS = False )
157+ def test_transformer_version (self ):
158+ self .registry .register ('test_event' )(DummyTransformer )
159+ raw_event = self .get_raw_event ('edx.course.enrollment.activated.json' )
160+ transformed_event = self .registry .get_transformer (raw_event ).transform ()
161+ self .assert_correct_transformer_version (transformed_event , 'event-routing-backends@{}' .format (__version__ ))
162+
163+ @patch ('event_routing_backends.helpers.uuid.uuid4' )
164+ @ddt .data (* EVENT_FIXTURE_FILENAMES )
165+ def test_event_transformer (self , raw_event_file_path , mocked_uuid4 ):
166+ # Used to generate the anonymized actor.name,
167+ # which in turn is used to generate the event UUID.
168+ mocked_uuid4 .return_value = UUID ('32e08e30-f8ae-4ce2-94a8-c2bfe38a70cb' )
169+
170+ # if an event's expected fixture doesn't exist, the test shouldn't fail.
171+ # evaluate transformation of only supported event fixtures.
172+ base_event_filename = os .path .basename (raw_event_file_path )
173+
174+ expected_event_file_path = '{expected_events_fixture_path}/{event_filename}' .format (
175+ expected_events_fixture_path = self .expected_events_fixture_path , event_filename = base_event_filename
176+ )
177+
178+ if not os .path .isfile (expected_event_file_path ):
179+ return
180+
181+ self .check_event_transformer (raw_event_file_path , expected_event_file_path )
0 commit comments