Skip to content

Commit

Permalink
Merge pull request #77 from EPNW/new_visit
Browse files Browse the repository at this point in the history
New app launches should start new visits
  • Loading branch information
TesteurManiak authored May 12, 2023
2 parents 1f6552b + a93c959 commit 3dae32c
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/src/matomo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ class MatomoTracker {

late final int _dequeueInterval;

late bool _newVisit;

/// Initialize the tracker.
///
/// This method must be called before any other method. Otherwise they might
Expand All @@ -127,6 +129,10 @@ class MatomoTracker {
/// If the tracker is already initialized, an
/// [AlreadyInitializedMatomoInstanceException] will be thrown.
///
/// The [newVisit] parameter is used to mark this initialization the start
/// of a new visit. If set to `false` it is left to Matomo to decide if this
/// is a new visit or not.
///
/// The [visitorId] should have a length of 16 characters otherwise an
/// [ArgumentError] will be thrown. This parameter corresponds with the
/// `_id` and should not be confused with the user id `uid`.
Expand All @@ -137,6 +143,7 @@ class MatomoTracker {
Future<void> initialize({
required int siteId,
required String url,
bool newVisit = true,
String? visitorId,
String? uid,
String? contentBaseUrl,
Expand Down Expand Up @@ -172,6 +179,7 @@ class MatomoTracker {
_cookieless = cookieless;
_tokenAuth = tokenAuth;
_dispatcher = MatomoDispatcher(url, tokenAuth);
_newVisit = newVisit;

final effectiveLocalStorage = localStorage ?? SharedPrefsStorage();
_localStorage = cookieless
Expand Down Expand Up @@ -566,7 +574,12 @@ class MatomoTracker {
}

void _track(MatomoEvent event) {
queue.add(event);
var ev = event;
if (_newVisit) {
ev = ev.copyWith(newVisit: true);
_newVisit = false;
}
queue.add(ev);
}

FutureOr<void> _dequeue() {
Expand Down
51 changes: 51 additions & 0 deletions lib/src/matomo_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class MatomoEvent {
this.link,
this.campaign,
this.dimensions,
this.newVisit,
}) :
// we use clock.now instead of DateTime.now to make testing easier
_date = clock.now().toUtc(),
Expand Down Expand Up @@ -79,6 +80,53 @@ class MatomoEvent {
// The dimensions associated with the event
final Map<String, String>? dimensions;

final bool? newVisit;

MatomoEvent copyWith({
MatomoTracker? tracker,
String? path,
String? action,
EventInfo? eventInfo,
String? screenId,
int? goalId,
String? orderId,
List<TrackingOrderItem>? trackingOrderItems,
num? revenue,
num? subTotal,
num? taxAmount,
num? shippingCost,
num? discountAmount,
String? searchKeyword,
String? searchCategory,
int? searchCount,
String? link,
Campaign? campaign,
Map<String, String>? dimensions,
bool? newVisit,
}) =>
MatomoEvent(
tracker: tracker ?? this.tracker,
path: path ?? this.path,
action: action ?? this.action,
eventInfo: eventInfo ?? this.eventInfo,
screenId: screenId ?? this.screenId,
goalId: goalId ?? this.goalId,
orderId: orderId ?? this.orderId,
trackingOrderItems: trackingOrderItems ?? this.trackingOrderItems,
revenue: revenue ?? this.revenue,
subTotal: subTotal ?? this.subTotal,
taxAmount: taxAmount ?? this.taxAmount,
shippingCost: shippingCost ?? this.shippingCost,
discountAmount: discountAmount ?? this.discountAmount,
searchKeyword: searchKeyword ?? this.searchKeyword,
searchCategory: searchCategory ?? this.searchCategory,
searchCount: searchCount ?? this.searchCount,
link: link ?? this.link,
campaign: campaign ?? this.campaign,
dimensions: dimensions ?? this.dimensions,
newVisit: newVisit ?? this.newVisit,
);

Map<String, String> toMap() {
final id = tracker.visitor.id;
final uid = tracker.visitor.uid;
Expand Down Expand Up @@ -108,12 +156,15 @@ class MatomoEvent {
final dims = dimensions;
final locale = PlatformDispatcher.instance.locale;
final country = locale.countryCode;
final nV = newVisit;

return {
// Required parameters
'idsite': tracker.siteId.toString(),
'rec': '1',

if (nV != null && nV) 'new_visit': '1',

// Recommended parameters
if (actionName != null) 'action_name': actionName,
'url': url,
Expand Down
2 changes: 2 additions & 0 deletions test/ressources/mock/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const matomoCampaignContent = 'content';
const matomoCampaignId = 'id';
const matomoCampaignGroup = 'group';
const matomoCampaignPlacement = 'placement';
const matomoNewVisit = false;
const matomoChangedNewVisit = true;
const matomoEventPath = 'path';
const matomoEventAction = 'action';
const matomoEventCategory = 'eventCategory';
Expand Down
103 changes: 103 additions & 0 deletions test/src/matomo_event_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void main() {
subTotal: matomoSubTotal,
taxAmount: matomoTaxAmount,
trackingOrderItems: matomoTrackingOrderItems,
newVisit: matomoNewVisit,
);
}

Expand Down Expand Up @@ -72,6 +73,7 @@ void main() {
expect(matomotoEvent.subTotal, matomoSubTotal);
expect(matomotoEvent.taxAmount, matomoTaxAmount);
expect(matomotoEvent.trackingOrderItems, matomoTrackingOrderItems);
expect(matomotoEvent.newVisit, matomoNewVisit);
});

group(
Expand Down Expand Up @@ -207,4 +209,105 @@ void main() {
});
});
});

group('copyWith', () {
setUpAll(() {
when(() => mockMatomoTracker.visitor).thenReturn(mockVisitor);
when(() => mockMatomoTracker.session).thenReturn(mockSession);
when(() => mockMatomoTracker.screenResolution)
.thenReturn(matomoTrackerScreenResolution);
when(() => mockMatomoTracker.contentBase)
.thenReturn(matomoTrackerContentBase);
when(() => mockMatomoTracker.siteId).thenReturn(matomoTrackerSiteId);
when(() => mockVisitor.id).thenReturn(visitorId);
when(() => mockVisitor.uid).thenReturn(uid);
when(mockTrackingOrderItem.toArray).thenReturn([]);
when(() => mockSession.visitCount).thenReturn(sessionVisitCount);
when(() => mockSession.lastVisit).thenReturn(sessionLastVisite);
when(() => mockSession.firstVisit).thenReturn(sessionFirstVisite);
});

test('it should be able to create a unchanged copy', () {
final fixedDate = DateTime(2022).toUtc();

withClock(Clock.fixed(fixedDate), () {
final matomotoEvent = getCompleteMatomoEvent();
final unchangedCopy = matomotoEvent.copyWith();

expect(matomotoEvent.tracker, unchangedCopy.tracker);
expect(matomotoEvent.path, unchangedCopy.path);
expect(matomotoEvent.action, unchangedCopy.action);
expect(
matomotoEvent.eventInfo?.category,
unchangedCopy.eventInfo?.category,
);
expect(matomotoEvent.dimensions, unchangedCopy.dimensions);
expect(matomotoEvent.discountAmount, unchangedCopy.discountAmount);
expect(
matomotoEvent.eventInfo?.action,
unchangedCopy.eventInfo?.action,
);
expect(matomotoEvent.eventInfo?.value, unchangedCopy.eventInfo?.value);
expect(matomotoEvent.eventInfo?.name, unchangedCopy.eventInfo?.name);
expect(matomotoEvent.goalId, unchangedCopy.goalId);
expect(matomotoEvent.link, unchangedCopy.link);
expect(matomotoEvent.orderId, unchangedCopy.orderId);
expect(matomotoEvent.revenue, unchangedCopy.revenue);
expect(matomotoEvent.screenId, unchangedCopy.screenId);
expect(matomotoEvent.searchCategory, unchangedCopy.searchCategory);
expect(matomotoEvent.searchCount, unchangedCopy.searchCount);
expect(matomotoEvent.searchKeyword, unchangedCopy.searchKeyword);
expect(matomotoEvent.shippingCost, unchangedCopy.shippingCost);
expect(matomotoEvent.subTotal, unchangedCopy.subTotal);
expect(matomotoEvent.taxAmount, unchangedCopy.taxAmount);
expect(
matomotoEvent.trackingOrderItems,
unchangedCopy.trackingOrderItems,
);
expect(matomotoEvent.newVisit, unchangedCopy.newVisit);
});
});

test('it should be able to create a changed copy', () {
final fixedDate = DateTime(2022).toUtc();

withClock(Clock.fixed(fixedDate), () {
final matomotoEvent = getCompleteMatomoEvent();
final changedCopy =
matomotoEvent.copyWith(newVisit: matomoChangedNewVisit);

expect(matomotoEvent.tracker, changedCopy.tracker);
expect(matomotoEvent.path, changedCopy.path);
expect(matomotoEvent.action, changedCopy.action);
expect(
matomotoEvent.eventInfo?.category,
changedCopy.eventInfo?.category,
);
expect(matomotoEvent.dimensions, changedCopy.dimensions);
expect(matomotoEvent.discountAmount, changedCopy.discountAmount);
expect(
matomotoEvent.eventInfo?.action,
changedCopy.eventInfo?.action,
);
expect(matomotoEvent.eventInfo?.value, changedCopy.eventInfo?.value);
expect(matomotoEvent.eventInfo?.name, changedCopy.eventInfo?.name);
expect(matomotoEvent.goalId, changedCopy.goalId);
expect(matomotoEvent.link, changedCopy.link);
expect(matomotoEvent.orderId, changedCopy.orderId);
expect(matomotoEvent.revenue, changedCopy.revenue);
expect(matomotoEvent.screenId, changedCopy.screenId);
expect(matomotoEvent.searchCategory, changedCopy.searchCategory);
expect(matomotoEvent.searchCount, changedCopy.searchCount);
expect(matomotoEvent.searchKeyword, changedCopy.searchKeyword);
expect(matomotoEvent.shippingCost, changedCopy.shippingCost);
expect(matomotoEvent.subTotal, changedCopy.subTotal);
expect(matomotoEvent.taxAmount, changedCopy.taxAmount);
expect(
matomotoEvent.trackingOrderItems,
changedCopy.trackingOrderItems,
);
expect(matomoChangedNewVisit, changedCopy.newVisit);
});
});
});
}
9 changes: 9 additions & 0 deletions test/src/matomo_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ void main() {
testTracking('it should be able to trackOutlink', (tracker) async {
tracker.trackOutlink(null);
});

test('it should be able to handle new_visit', () async {
final matomoTracker = await getInitializedMatomoTracker();

matomoTracker.trackDimensions(matomoTrackerDimensions);
expect(matomoTracker.queue.first.newVisit, true);
matomoTracker.trackDimensions(matomoTrackerDimensions);
expect(matomoTracker.queue.last.newVisit, null);
});
});

group('setVisitorUserId', () {
Expand Down

0 comments on commit 3dae32c

Please sign in to comment.