package de.superx.bianalysis; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import de.superx.BaseDbTest; import de.superx.bianalysis.models.Right; import de.superx.bianalysis.rest.BiAnalysisApi; import de.superx.bianalysis.service.BiAnalysisManager; import de.superx.bianalysis.service.DbMetaAdapter; import static de.superx.BIATestUtils.getParsedSqlFromString; import static de.superx.BIATestUtils.getTotalColumnSqlFromReportDefinition; import static de.superx.BIATestUtils.getSqlFromReportDefinition; public class BiAnalysisTest extends BaseDbTest { @Autowired BiAnalysisApi biAnalysis; @Autowired DbMetaAdapter dbAdapter; @Before public void init() { setRight(Right.CREATE_ANALYSIS); } // TODO: This test fails on the server but passes locally because the selected // top dimension attribute values are returned in a different order. // // When no sort_order_column exists, dimension attribute values should be sorted // alphabetically so that the generated query is deterministic across environments. // // Locally, "col2" is generated as: // COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' // AND conformed_publication.visibility = 'öffentlich') AS "col2", // // On the server, "col2" is generated as: // COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' // AND conformed_publication.visibility = 'versteckt') AS "col2", @Ignore @Test public void selectAllReportOptions() { String json = """ { "factTableId": "res_pub:1", "filters": [ { "dimensionAttributeId": "conf_res:20", "filterValues": [ "ja", "nein" ] }, { "dimensionAttributeId": "conf_res:21", "filterValues": [ "Fachzeitschrift für Produktions- und Verfahrenstechnik", "Financial Review", "Finanzwissenschaft", "Genetic Review", "International Journal of Financial Studies" ] }, { "dimensionAttributeId": "res_pub:38", "filterValues": [ "2021", "2022", "2023" ] } ], "leftDimensionAttributeIds": [ "res_pub:38" ], "measureIds": [ "res_pub:21037", "res_pub:21031" ], "topDimensionAttributeIds": [ "conf_res:20", "conf_res:26" ] } """; String expectedSql = """ SELECT date.year_actual AS year_actual_38, date.year_actual_sort_order AS year_actual_38_year_actual_sort_order, COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'hochschulweit') AS "col0", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'hochschulweit') AS "col1", COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'öffentlich') AS "col2", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'öffentlich') AS "col3", COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'versteckt') AS "col4", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'ja' AND conformed_publication.visibility = 'versteckt') AS "col5", COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'hochschulweit') AS "col6", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'hochschulweit') AS "col7", COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'öffentlich') AS "col8", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'öffentlich') AS "col9", COUNT(DISTINCT fact_publication.publication_id) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'versteckt') AS "col10", SUM(fact_publication.share_publication) FILTER ( WHERE conformed_publication.peer_reviewed = 'nein' AND conformed_publication.visibility = 'versteckt') AS "col11" FROM presentation.fact_publication JOIN presentation.dim_date AS date ON fact_publication.publication_date_id = date.id JOIN presentation.dim_publication AS conformed_publication ON fact_publication.publication_id = conformed_publication.id WHERE conformed_publication.peer_reviewed IN ('ja', 'nein') AND conformed_publication.journal IN ('Fachzeitschrift für Produktions- und Verfahrenstechnik', 'Financial Review', 'Finanzwissenschaft', 'Genetic Review', 'International Journal of Financial Studies') AND date.year_actual IN ('2021', '2022', '2023') GROUP BY GROUPING SETS ((date.year_actual, date.year_actual_sort_order), ()) ORDER BY date.year_actual_sort_order """; String actualSqlParsed = getSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } @Test public void selectNoColumns() { String json = """ { "factTableId": "res_pub:1", "filters": [], "leftDimensionAttributeIds": [ "conf_res:18", "conf_res:20" ], "measureIds": [ "res_pub:21037", "res_pub:21031" ], "topDimensionAttributeIds": [] } """; String expectedSql = """ SELECT conformed_publication.title AS title_18, conformed_publication.peer_reviewed AS peer_reviewed_20, COUNT(DISTINCT (fact_publication.publication_id)) AS "col0", SUM(fact_publication.share_publication) AS "col1" FROM presentation.fact_publication JOIN presentation.dim_publication AS conformed_publication ON fact_publication.publication_id = conformed_publication.id GROUP BY GROUPING SETS ((conformed_publication.title, conformed_publication.peer_reviewed), (conformed_publication.title), ()) ORDER BY title_18, peer_reviewed_20 """; String actualSqlParsed = getSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } @Test public void selectFilterWithoutDisplayingItsDimensionInCrossTable() { String json = """ { "factTableId": "res_pub:1", "filters": [ { "dimensionAttributeId": "conf:3151", "filterValues": [ "deutsch" ] } ], "hideEmptyColumns": false, "leftDimensionAttributeIds": [ "conf_res:18", "conf_res:20" ], "measureIds": [ "res_pub:21037", "res_pub:21031" ], "topDimensionAttributeIds": [] } """; String expectedSql = """ SELECT conformed_publication.title AS title_18, conformed_publication.peer_reviewed AS peer_reviewed_20, COUNT(DISTINCT (fact_publication.publication_id)) AS "col0", SUM(fact_publication.share_publication) AS "col1" FROM presentation.fact_publication JOIN presentation.dim_publication AS conformed_publication ON fact_publication.publication_id = conformed_publication.id JOIN presentation.dim_language AS language ON fact_publication.language_id = language.id WHERE language.iso_language IN ('deutsch') GROUP BY GROUPING SETS ((conformed_publication.title, conformed_publication.peer_reviewed), (conformed_publication.title), ()) ORDER BY title_18, peer_reviewed_20 """; String actualSqlParsed = getSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } @Test public void selectDifferentDimensionsWithSameDimTableName() { String json = """ { "factTableId": "app_basic:1", "filters": [], "leftDimensionAttributeIds": [ "app_basic:63", "app_basic:57" ], "measureIds": [ "app_basic:80" ], "topDimensionAttributeIds": [] } """; String expectedSql = """ SELECT date.year_actual AS year_actual_63, date.year_actual_sort_order AS year_actual_63_year_actual_sort_order, date.year_actual AS year_actual_57, date.year_actual_sort_order AS year_actual_57_year_actual_sort_order, COUNT(DISTINCT (fact_application.person_id)) AS "col0" FROM presentation.fact_application JOIN presentation.dim_date AS date ON fact_application.receipt_date_id = date.id GROUP BY GROUPING SETS ((date.year_actual, date.year_actual_sort_order, date.year_actual, date.year_actual_sort_order), (date.year_actual, date.year_actual_sort_order), ()) ORDER BY date.year_actual_sort_order, date.year_actual_sort_order """; String actualSqlParsed = getSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } @Test public void selectAttributeWithSortOrderColumn() { String json = """ { "factTableId": "res:66", "measureIds":[ "res:104" ], "leftDimensionAttributeIds":[ "res:78" ], "topDimensionAttributeIds":[ ], "filters": [] } """; String expectedSql = """ SELECT project_start_date.month_name AS month_name_78, project_start_date.month_actual_sort_order AS month_name_78_month_actual_sort_order, COUNT(DISTINCT (fact_project.project_id)) AS "col0" FROM presentation.fact_project JOIN presentation.dim_date AS project_start_date ON fact_project.project_start_date_id = project_start_date.id GROUP BY GROUPING SETS ((project_start_date.month_name, project_start_date.month_actual_sort_order), ()) ORDER BY project_start_date.month_actual_sort_order """; String actualSqlParsed = getSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } @Test public void testTotalsColumnOnlyMeasures() throws JsonMappingException, JsonProcessingException { String json = """ { "factTableId": "res:66", "measureIds":[ "res:104" ], "leftDimensionAttributeIds":[ "res:78" ], "topDimensionAttributeIds":[ ], "filters": [] } """; ReportDefinition definition = new ObjectMapper().readValue(json, ReportDefinition.class); String sql = BiAnalysisManager.getTotalsColumnSqlStatement(definition, dbAdapter); assertEquals("", sql); } @Test public void testTotalsColumnWithTopAttributes() { String json = """ { "factTableId": "res_pub:1", "filters": [], "leftDimensionAttributeIds": [ "conf:50" ], "measureIds": [ "res_pub:21031", "res_pub:21037" ], "topDimensionAttributeIds": [ "conf_res:20" ] } """; String expectedSql = """ SELECT date.year_actual AS year_actual_50, date.year_actual_sort_order AS year_actual_50_year_actual_sort_order, SUM(fact_publication.share_publication) AS "col0", COUNT(DISTINCT (fact_publication.publication_id)) AS "col1" FROM presentation.fact_publication JOIN presentation.dim_date AS date ON fact_publication.date_id = date.id JOIN presentation.dim_publication AS conformed_publication ON fact_publication.publication_id = conformed_publication.id WHERE conformed_publication.peer_reviewed IN ('n. v.', 'ja', 'nein') GROUP BY GROUPING SETS ((date.year_actual, date.year_actual_sort_order), ()) ORDER BY date.year_actual_sort_order """; String actualSqlParsed = getTotalColumnSqlFromReportDefinition(json, dbAdapter); String expectedSqlParsed = getParsedSqlFromString(expectedSql); assertEquals(expectedSqlParsed, actualSqlParsed); } }