From 10ff174dab1292585b4523b056b322c8cf62d5cf Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 11 Jan 2024 19:41:11 +0100 Subject: [PATCH 1/2] fix: added unit test --- pubspec.yaml | 2 +- test/src/matomo_action_test.dart | 48 ++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index b25ee93..8372fc3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,6 @@ dev_dependencies: flutter_test: sdk: flutter meta: ^1.9.1 - mocktail: ^1.0.1 + mocktail: ^1.0.2 flutter: null diff --git a/test/src/matomo_action_test.dart b/test/src/matomo_action_test.dart index 81529ed..d5925b3 100644 --- a/test/src/matomo_action_test.dart +++ b/test/src/matomo_action_test.dart @@ -12,9 +12,12 @@ import '../ressources/mock/data.dart'; import '../ressources/mock/mock.dart'; void main() { - MatomoAction getCompleteMatomoAction() { + MatomoAction getCompleteMatomoAction({ + String path = matomoActionPath, + bool withCampaign = true, + }) { return MatomoAction( - path: matomoActionPath, + path: path, action: matomoActionName, dimensions: matomoEventDimension, discountAmount: matomoDiscountAmount, @@ -24,16 +27,18 @@ void main() { name: matomoEventName, value: matomoEventValue, ), - campaign: Campaign( - name: matomoCampaignName, - keyword: matomoCampaignKeyword, - source: matomoCampaignSource, - medium: matomoCampaignMedium, - content: matomoCampaignContent, - id: matomoCampaignId, - group: matomoCampaignGroup, - placement: matomoCampaignPlacement, - ), + campaign: withCampaign + ? Campaign( + name: matomoCampaignName, + keyword: matomoCampaignKeyword, + source: matomoCampaignSource, + medium: matomoCampaignMedium, + content: matomoCampaignContent, + id: matomoCampaignId, + group: matomoCampaignGroup, + placement: matomoCampaignPlacement, + ) + : null, content: Content( name: matomoContentName, piece: matomoContentPiece, @@ -247,6 +252,25 @@ void main() { expect(mapEquals(wantedEvent, eventMap), isTrue); }); }); + + test('Issue #132: bad url encoding', () { + final fixedDate = DateTime(2022).toUtc(); + const contentBase = 'https://app.articlett.schule/#/'; + const localPath = 'sherlock'; + const expectedUrl = "https%3A%2F%2Fapp.articlett.schule%2F%23%2Fsherlock"; + + when(() => mockMatomoTracker.contentBase).thenReturn(contentBase); + + withClock(Clock.fixed(fixedDate), () { + final matomoAction = getCompleteMatomoAction( + path: localPath, + withCampaign: false, + ); + final eventMap = matomoAction.toMap(mockMatomoTracker); + + expect(eventMap['url'], expectedUrl); + }); + }); }); group('copyWith', () { From d2654c8160aecfda6fe9012d59b7c2ac53833d0a Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 11 Jan 2024 19:55:07 +0100 Subject: [PATCH 2/2] fix: fixed parsing of Uri --- lib/src/matomo_action.dart | 39 +++++++++++++++++++++++--------- test/src/matomo_action_test.dart | 3 +-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/src/matomo_action.dart b/lib/src/matomo_action.dart index 3c34639..5a23b67 100644 --- a/lib/src/matomo_action.dart +++ b/lib/src/matomo_action.dart @@ -167,17 +167,23 @@ class MatomoAction { final camp = campaign; final campKeyword = camp?.keyword; final localPath = path; - final uri = Uri.parse( - localPath != null - ? '${tracker.contentBase}${localPath.prefixWithSlash()}' - : tracker.contentBase, - ); - final url = uri.replace( - queryParameters: { - if (camp != null) ...camp.toMap(), - ...uri.queryParameters, - }, - ).toString(); + + final baseUrl = (localPath != null + ? '${tracker.contentBase.removeTrailingSlash()}${localPath.prefixWithSlash()}' + : tracker.contentBase) + .replaceHashtags(); + final uri = Uri.parse(baseUrl); + final url = uri + .replace( + queryParameters: camp != null || uri.queryParameters.isNotEmpty + ? { + if (camp != null) ...camp.toMap(), + ...uri.queryParameters, + } + : null, + ) + .toString() + .restoreHashtags(); final idgoal = goalId; final aRevenue = revenue; final event = eventInfo; @@ -272,3 +278,14 @@ class MatomoAction { }; } } + +extension on String { + String removeTrailingSlash() { + if (endsWith('/')) return substring(0, length - 1); + return this; + } + + static const _placeholder = 'HASHTAG_PLACEHOLDER'; + String replaceHashtags() => replaceAll('/#/', '/$_placeholder/'); + String restoreHashtags() => replaceAll('/$_placeholder/', '/#/'); +} diff --git a/test/src/matomo_action_test.dart b/test/src/matomo_action_test.dart index d5925b3..e6fa98d 100644 --- a/test/src/matomo_action_test.dart +++ b/test/src/matomo_action_test.dart @@ -267,8 +267,7 @@ void main() { withCampaign: false, ); final eventMap = matomoAction.toMap(mockMatomoTracker); - - expect(eventMap['url'], expectedUrl); + expect(Uri.encodeQueryComponent(eventMap['url'] ?? ''), expectedUrl); }); }); });