44
55import org .apache .spark .sql .Row ;
66import org .apache .spark .sql .catalyst .expressions .GenericRowWithSchema ;
7+ import org .apache .spark .sql .types .DataTypes ;
78import org .apache .spark .sql .types .StructType ;
89import org .junit .jupiter .params .ParameterizedTest ;
910import org .junit .jupiter .params .provider .CsvSource ;
1011
1112import java .util .Collections ;
1213import java .util .Iterator ;
1314import java .util .List ;
15+ import java .util .Map ;
1416
1517import static com .digitalpebble .spruce .CURColumn .*;
1618import static org .junit .jupiter .api .Assertions .assertEquals ;
2325 */
2426public class EnrichmentPipelineTest {
2527
28+ /** A lightweight test column used by DummyModule to verify enrichment. */
29+ private static final Column DUMMY_ENRICHED = new Column ("dummy_enriched" , DataTypes .DoubleType ) {};
30+
31+ /**
32+ * Minimal {@link EnrichmentModule} for testing pipeline logic.
33+ * Declares a single output column and sets it to a fixed value during process().
34+ */
35+ static class DummyModule implements EnrichmentModule {
36+
37+ @ Override
38+ public Column [] columnsNeeded () {
39+ return new Column [0 ];
40+ }
41+
42+ @ Override
43+ public Column [] columnsAdded () {
44+ return new Column []{ DUMMY_ENRICHED };
45+ }
46+
47+ @ Override
48+ public Row process (Row row ) {
49+ return EnrichmentModule .withUpdatedValue (row , DUMMY_ENRICHED , 42.0 );
50+ }
51+ }
52+
53+ /**
54+ * Creates a Config pre-loaded with a single DummyModule.
55+ * This avoids loading the real production modules (which require the full CUR schema)
56+ * and keeps the test focused on the pipeline's Usage-filter logic.
57+ */
58+ private static Config createMockConfig () {
59+ Config config = new Config ();
60+ DummyModule module = new DummyModule ();
61+ config .getModules ().add (module );
62+
63+ // Also inject matching config entry via reflection so configureModules() works
64+ try {
65+ var configsField = Config .class .getDeclaredField ("configs" );
66+ configsField .setAccessible (true );
67+ @ SuppressWarnings ("unchecked" )
68+ List <Map <String , Object >> configs =
69+ (List <Map <String , Object >>) configsField .get (config );
70+ configs .add (Collections .emptyMap ());
71+ } catch (Exception e ) {
72+ throw new RuntimeException ("Failed to set up mock config" , e );
73+ }
74+
75+ return config ;
76+ }
77+
2678 /**
2779 * Verifies the selective enrichment logic based on Line Item Type.
2880 * <p>
@@ -39,21 +91,18 @@ public class EnrichmentPipelineTest {
3991 "Fee, false"
4092 })
4193 public void testPipelineEnrichmentLogic (String lineItemType , boolean expectEnrichment ) throws Exception {
42- Config config = new Config ();
94+ Config config = createMockConfig ();
4395 EnrichmentPipeline pipeline = new EnrichmentPipeline (config );
4496
45- // TODO: Validate that modules are loaded (Option 1 - Mocking).
46- // Currently, new Config() returns an empty list in unit tests.
47- // We will implement a Mock Config in a separate PR to handle this without
48- // requiring the full production schema.
49- // assertFalse(config.getModules().isEmpty(), "Config should have at least one enrichment module");
97+ List <EnrichmentModule > modules = config .getModules ();
98+ assertFalse (modules .isEmpty (), "Config should have at least one enrichment module for this test" );
5099
51- // Minimal schema: use ONLY existing constants in CURColumn.
100+ // Minimal schema: base CUR columns + columns added by the DummyModule
52101 StructType schema = new StructType ()
53102 .add (PRODUCT_REGION_CODE .getLabel (), PRODUCT_REGION_CODE .getType (), true )
54103 .add (LINE_ITEM_TYPE .getLabel (), LINE_ITEM_TYPE .getType (), true );
55104
56- for (EnrichmentModule module : config . getModules () ) {
105+ for (EnrichmentModule module : modules ) {
57106 for (Column c : module .columnsAdded ()) {
58107 schema = schema .add (c .getLabel (), c .getType (), true );
59108 }
@@ -75,7 +124,7 @@ public void testPipelineEnrichmentLogic(String lineItemType, boolean expectEnric
75124 assertEquals ("us-east-1" , PRODUCT_REGION_CODE .getString (processedRow ));
76125
77126 // Verify enrichment logic
78- for (EnrichmentModule module : config . getModules () ) {
127+ for (EnrichmentModule module : modules ) {
79128 for (Column c : module .columnsAdded ()) {
80129 int fieldIndex = processedRow .fieldIndex (c .getLabel ());
81130 if (expectEnrichment ) {
0 commit comments