Created
February 19, 2026 05:44
-
-
Save musketyr/cb80c17a6a0dd12c60a3dda89d3d9965 to your computer and use it in GitHub Desktop.
Spock to JUnit 5 Migration Diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Spock → JUnit 5 Migration: GoogleAnalyticsResponseUtilsSpec</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; padding: 20px; line-height: 1.6; } | |
| h1 { text-align: center; margin-bottom: 20px; color: #333; } | |
| .section { background: white; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: hidden; } | |
| .section-header { background: #2d3748; color: white; padding: 12px 16px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; } | |
| .section-header:hover { background: #4a5568; } | |
| .section-header h2 { font-size: 16px; font-weight: 600; } | |
| .section-header .toggle { font-size: 12px; } | |
| .section-content { display: block; } | |
| .section-content.collapsed { display: none; } | |
| .diff-container { display: grid; grid-template-columns: 1fr 1fr; } | |
| .diff-panel { padding: 16px; overflow-x: auto; } | |
| .diff-panel.left { background: #fff5f5; border-right: 1px solid #e2e8f0; } | |
| .diff-panel.right { background: #f0fff4; } | |
| .diff-panel h3 { font-size: 12px; text-transform: uppercase; color: #718096; margin-bottom: 12px; letter-spacing: 0.5px; } | |
| pre { font-family: 'SF Mono', Monaco, 'Courier New', monospace; font-size: 13px; white-space: pre-wrap; word-wrap: break-word; } | |
| .left pre { color: #c53030; } | |
| .right pre { color: #276749; } | |
| @media (max-width: 768px) { .diff-container { grid-template-columns: 1fr; } .diff-panel.left { border-right: none; border-bottom: 1px solid #e2e8f0; } } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>🦀 Spock → JUnit 5 Migration: GoogleAnalyticsResponseUtilsSpec</h1> | |
| <p style="text-align: center; color: #666; margin-bottom: 20px;">Story: <a href="https://app.shortcut.com/agorapulse/story/185894">sc185894</a> | PR: <a href="https://github.com/agorapulse/platform/pull/72991">#72991</a></p> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>📦 Imports</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre>package agorapulse.roi.service.google.client.analytics.api | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Header | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Row | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Value | |
| import spock.lang.Specification</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>package agorapulse.roi.service.google.client.analytics.api; | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Header; | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Row; | |
| import agorapulse.roi.service.google.client.analytics.api.Ga4InsightsApiResponse.Value; | |
| import org.junit.jupiter.api.Test; | |
| import java.util.List; | |
| import java.util.Map; | |
| import static org.assertj.core.api.Assertions.assertThat; | |
| import static org.assertj.core.api.Assertions.assertThatThrownBy;</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🏗️ Class & Fields</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre>class GoogleAnalyticsResponseUtilsSpec extends Specification { | |
| </pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>class GoogleAnalyticsResponseUtilsTest { | |
| </pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should map response headers with values</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should map response headers with values'() { | |
| given: | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')]), | |
| ] | |
| ) | |
| when: | |
| Map<String, String> response = GoogleAnalyticsResponseUtils.mapHeadersWithValues(eventsResponse.metricHeaders, eventsResponse.rows.get(0).metricValues) | |
| then: | |
| response == [eventValue: '2.0', eventCount: '7', transactions: '17', purchaseRevenue: '29.0'] | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldMapResponseHeadersWithValues() { | |
| // given | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| )); | |
| eventsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("2.0", "7", "17", "29.0")) | |
| )); | |
| // when | |
| Map<String, String> response = GoogleAnalyticsResponseUtils.mapHeadersWithValues( | |
| eventsResponse.getMetricHeaders(), | |
| eventsResponse.getRows().get(0).getMetricValues() | |
| ); | |
| // then | |
| assertThat(response).containsExactlyInAnyOrderEntriesOf(Map.of( | |
| "eventValue", "2.0", | |
| "eventCount", "7", | |
| "transactions", "17", | |
| "purchaseRevenue", "29.0" | |
| )); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should map response headers with values - headers size greater than values size</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should map response headers with values - headers size greater than values size'() { | |
| given: | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '2.0')]), | |
| ] | |
| ) | |
| when: | |
| Map<String, String> response = GoogleAnalyticsResponseUtils.mapHeadersWithValues(eventsResponse.metricHeaders, eventsResponse.rows.get(0).metricValues) | |
| then: | |
| response == [eventValue: '2.0', eventCount: '0', transactions: '0', purchaseRevenue: '0.0'] | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldMapResponseHeadersWithValuesWhenHeadersSizeGreaterThanValuesSize() { | |
| // given | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| )); | |
| eventsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("2.0")) | |
| )); | |
| // when | |
| Map<String, String> response = GoogleAnalyticsResponseUtils.mapHeadersWithValues( | |
| eventsResponse.getMetricHeaders(), | |
| eventsResponse.getRows().get(0).getMetricValues() | |
| ); | |
| // then | |
| assertThat(response).containsExactlyInAnyOrderEntriesOf(Map.of( | |
| "eventValue", "2.0", | |
| "eventCount", "0", | |
| "transactions", "0", | |
| "purchaseRevenue", "0.0" | |
| )); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should map response headers with values - values size greater than headers size</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should map response headers with values - values size greater than headers size'() { | |
| given: | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')]), | |
| ] | |
| ) | |
| when: | |
| GoogleAnalyticsResponseUtils.mapHeadersWithValues(eventsResponse.metricHeaders, eventsResponse.rows.get(0).metricValues) | |
| then: | |
| Exception e = thrown(IllegalArgumentException) | |
| e.message == "Headers should have a size greater or equals than values, header size = 2, values size = 4" | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldThrowExceptionWhenValuesSizeGreaterThanHeadersSize() { | |
| // given | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount") | |
| )); | |
| eventsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("2.0", "7", "17", "29.0")) | |
| )); | |
| // when/then | |
| assertThatThrownBy(() -> GoogleAnalyticsResponseUtils.mapHeadersWithValues( | |
| eventsResponse.getMetricHeaders(), | |
| eventsResponse.getRows().get(0).getMetricValues() | |
| )) | |
| .isInstanceOf(IllegalArgumentException.class) | |
| .hasMessage("Headers should have a size greater or equals than values, header size = 2, values size = 4"); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should merge batch responses</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should merge batch responses'() { | |
| given: | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'totalUsers')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13')]), | |
| ], | |
| totals: [new Row(metricValues: [new Value(value: '15')])] | |
| ) | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date'), new Header(name: 'eventName')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')]), | |
| ], | |
| totals: [new Row(metricValues: [new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')])] | |
| ) | |
| when: | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse) | |
| then: | |
| mergedResponse.dimensionHeaders == [new Header(name: 'date')] | |
| mergedResponse.metricHeaders == [new Header(name: 'totalUsers'), new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')] | |
| mergedResponse.rows == [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10'), new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13'), new Value(value: '0.0'), new Value(value: '0'), new Value(value: '0'), new Value(value: '0.0')]), | |
| ] | |
| mergedResponse.totals == [ | |
| new Row(metricValues: [new Value(value: '15'), new Value(value: '2.0'), new Value(value: '7'), new Value(value: '17'), new Value(value: '29.0')]) | |
| ] | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldMergeBatchResponses() { | |
| // given | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse(); | |
| visitorsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| visitorsResponse.setMetricHeaders(List.of(new Header("totalUsers"))); | |
| visitorsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("10")), | |
| createRow(List.of("20230102"), List.of("13")) | |
| )); | |
| visitorsResponse.setTotals(List.of(createRowWithMetricsOnly(List.of("15")))); | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"), new Header("eventName"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| )); | |
| eventsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("2.0", "7", "17", "29.0")) | |
| )); | |
| eventsResponse.setTotals(List.of(createRowWithMetricsOnly(List.of("2.0", "7", "17", "29.0")))); | |
| // when | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse); | |
| // then | |
| assertThat(mergedResponse.getDimensionHeaders()).containsExactly(new Header("date")); | |
| assertThat(mergedResponse.getMetricHeaders()).containsExactly( | |
| new Header("totalUsers"), | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| ); | |
| assertThat(mergedResponse.getRows()).containsExactly( | |
| createRow(List.of("20230101"), List.of("10", "2.0", "7", "17", "29.0")), | |
| createRow(List.of("20230102"), List.of("13", "0.0", "0", "0", "0.0")) | |
| ); | |
| assertThat(mergedResponse.getTotals()).containsExactly( | |
| createRowWithMetricsOnly(List.of("15", "2.0", "7", "17", "29.0")) | |
| ); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should merge batch responses - 0 event</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should merge batch responses - 0 event'() { | |
| given: | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'totalUsers')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13')]), | |
| ], | |
| totals: [new Row(metricValues: [new Value(value: '15')])] | |
| ) | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date'), new Header(name: 'eventName')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')], | |
| totals: [new Row()] | |
| ) | |
| when: | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse) | |
| then: | |
| mergedResponse.dimensionHeaders == [new Header(name: 'date')] | |
| mergedResponse.metricHeaders == [new Header(name: 'totalUsers'), new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')] | |
| mergedResponse.rows == [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10'), new Value(value: '0.0'), new Value(value: '0'), new Value(value: '0'), new Value(value: '0.0')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13'), new Value(value: '0.0'), new Value(value: '0'), new Value(value: '0'), new Value(value: '0.0')]), | |
| ] | |
| mergedResponse.totals == [ | |
| new Row(metricValues: [new Value(value: '15'), new Value(value: '0.0'), new Value(value: '0'), new Value(value: '0'), new Value(value: '0.0')]) | |
| ] | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldMergeBatchResponsesWithZeroEvents() { | |
| // given | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse(); | |
| visitorsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| visitorsResponse.setMetricHeaders(List.of(new Header("totalUsers"))); | |
| visitorsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("10")), | |
| createRow(List.of("20230102"), List.of("13")) | |
| )); | |
| visitorsResponse.setTotals(List.of(createRowWithMetricsOnly(List.of("15")))); | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"), new Header("eventName"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| )); | |
| eventsResponse.setTotals(List.of(new Row())); | |
| // when | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse); | |
| // then | |
| assertThat(mergedResponse.getDimensionHeaders()).containsExactly(new Header("date")); | |
| assertThat(mergedResponse.getMetricHeaders()).containsExactly( | |
| new Header("totalUsers"), | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| ); | |
| assertThat(mergedResponse.getRows()).containsExactly( | |
| createRow(List.of("20230101"), List.of("10", "0.0", "0", "0", "0.0")), | |
| createRow(List.of("20230102"), List.of("13", "0.0", "0", "0", "0.0")) | |
| ); | |
| assertThat(mergedResponse.getTotals()).containsExactly( | |
| createRowWithMetricsOnly(List.of("15", "0.0", "0", "0", "0.0")) | |
| ); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Should merge batch responses - all events</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'Should merge batch responses - all events'() { | |
| given: | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date')], | |
| metricHeaders: [new Header(name: 'totalUsers')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13')]), | |
| ], | |
| totals: [new Row(metricValues: [new Value(value: '15')])] | |
| ) | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse( | |
| dimensionHeaders: [new Header(name: 'date'), new Header(name: 'eventName')], | |
| metricHeaders: [new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')], | |
| rows: [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '5.0'), new Value(value: '18'), new Value(value: '36'), new Value(value: '60.0')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '5.0'), new Value(value: '13'), new Value(value: '23'), new Value(value: '37.0')]), | |
| ], | |
| totals: [new Row(metricValues: [new Value(value: '10.0'), new Value(value: '31'), new Value(value: '59'), new Value(value: '97.0')])] | |
| ) | |
| when: | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse) | |
| then: | |
| mergedResponse.dimensionHeaders == [new Header(name: 'date')] | |
| mergedResponse.metricHeaders == [new Header(name: 'totalUsers'), new Header(name: 'eventValue'), new Header(name: 'eventCount'), new Header(name: 'transactions'), new Header(name: 'purchaseRevenue')] | |
| mergedResponse.rows == [ | |
| new Row(dimensionValues: [new Value(value: '20230101')], metricValues: [new Value(value: '10'), new Value(value: '5.0'), new Value(value: '18'), new Value(value: '36'), new Value(value: '60.0')]), | |
| new Row(dimensionValues: [new Value(value: '20230102')], metricValues: [new Value(value: '13'), new Value(value: '5.0'), new Value(value: '13'), new Value(value: '23'), new Value(value: '37.0')]), | |
| ] | |
| mergedResponse.totals == [ | |
| new Row(metricValues: [new Value(value: '15'), new Value(value: '10.0'), new Value(value: '31'), new Value(value: '59'), new Value(value: '97.0')]) | |
| ] | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldMergeBatchResponsesWithAllEvents() { | |
| // given | |
| Ga4InsightsApiResponse visitorsResponse = new Ga4InsightsApiResponse(); | |
| visitorsResponse.setDimensionHeaders(List.of(new Header("date"))); | |
| visitorsResponse.setMetricHeaders(List.of(new Header("totalUsers"))); | |
| visitorsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("10")), | |
| createRow(List.of("20230102"), List.of("13")) | |
| )); | |
| visitorsResponse.setTotals(List.of(createRowWithMetricsOnly(List.of("15")))); | |
| Ga4InsightsApiResponse eventsResponse = new Ga4InsightsApiResponse(); | |
| eventsResponse.setDimensionHeaders(List.of(new Header("date"), new Header("eventName"))); | |
| eventsResponse.setMetricHeaders(List.of( | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| )); | |
| eventsResponse.setRows(List.of( | |
| createRow(List.of("20230101"), List.of("5.0", "18", "36", "60.0")), | |
| createRow(List.of("20230102"), List.of("5.0", "13", "23", "37.0")) | |
| )); | |
| eventsResponse.setTotals(List.of(createRowWithMetricsOnly(List.of("10.0", "31", "59", "97.0")))); | |
| // when | |
| Ga4InsightsApiResponse mergedResponse = GoogleAnalyticsResponseUtils.mergeBatchResponse(visitorsResponse, eventsResponse); | |
| // then | |
| assertThat(mergedResponse.getDimensionHeaders()).containsExactly(new Header("date")); | |
| assertThat(mergedResponse.getMetricHeaders()).containsExactly( | |
| new Header("totalUsers"), | |
| new Header("eventValue"), | |
| new Header("eventCount"), | |
| new Header("transactions"), | |
| new Header("purchaseRevenue") | |
| ); | |
| assertThat(mergedResponse.getRows()).containsExactly( | |
| createRow(List.of("20230101"), List.of("10", "5.0", "18", "36", "60.0")), | |
| createRow(List.of("20230102"), List.of("13", "5.0", "13", "23", "37.0")) | |
| ); | |
| assertThat(mergedResponse.getTotals()).containsExactly( | |
| createRowWithMetricsOnly(List.of("15", "10.0", "31", "59", "97.0")) | |
| ); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| function toggleSection(header) { | |
| const content = header.nextElementSibling; | |
| const toggle = header.querySelector('.toggle'); | |
| content.classList.toggle('collapsed'); | |
| toggle.textContent = content.classList.contains('collapsed') ? '▶' : '▼'; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment