From 7c073642f8413534605e7b98db1fc03ccfb55809 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Wed, 19 Apr 2023 22:50:55 -0400 Subject: [PATCH 1/5] feat(code_push_protocol): add subscription object to user --- .../lib/src/models/models.dart | 1 + .../lib/src/models/subscription.dart | 36 +++++++++++++++++++ .../lib/src/models/subscription.g.dart | 36 +++++++++++++++++++ .../lib/src/models/user.dart | 6 ++++ .../lib/src/models/user.g.dart | 6 ++++ 5 files changed, 85 insertions(+) create mode 100644 packages/shorebird_code_push_protocol/lib/src/models/subscription.dart create mode 100644 packages/shorebird_code_push_protocol/lib/src/models/subscription.g.dart diff --git a/packages/shorebird_code_push_protocol/lib/src/models/models.dart b/packages/shorebird_code_push_protocol/lib/src/models/models.dart index 6c74306ce..7cb4f1d5f 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/models.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/models.dart @@ -6,4 +6,5 @@ export 'patch.dart'; export 'patch_artifact.dart'; export 'release.dart'; export 'release_artifact.dart'; +export 'subscription.dart'; export 'user.dart'; diff --git a/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart b/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart new file mode 100644 index 000000000..4243558d3 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart @@ -0,0 +1,36 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; + +part 'subscription.g.dart'; + +/// {@template subscription} +/// TODO +/// {@endtemplate} +@JsonSerializable() +class Subscription { + /// {@macro subscription} + Subscription({ + required this.cost, + required this.paidThroughDate, + required this.willRenew, + }); + + /// Creates a [Subscription] from a JSON object. + factory Subscription.fromJson(Json json) => _$SubscriptionFromJson(json); + + /// Converts a [Subscription] to a JSON object. + Json toJson() => _$SubscriptionToJson(this); + + /// Billing rate, in cents. + final int cost; + + /// When the subscription will be renewed or expire. + @TimestampConverter() + final DateTime paidThroughDate; + + /// Whether this subscription will renew on [paidThroughDate]. + final bool willRenew; + + /// Whether this subscription is currently active. + bool get isActive => paidThroughDate.isAfter(DateTime.now()); +} diff --git a/packages/shorebird_code_push_protocol/lib/src/models/subscription.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/subscription.g.dart new file mode 100644 index 000000000..5568361e1 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/subscription.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars + +part of 'subscription.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Subscription _$SubscriptionFromJson(Map json) => + $checkedCreate( + 'Subscription', + json, + ($checkedConvert) { + final val = Subscription( + cost: $checkedConvert('cost', (v) => v as int), + paidThroughDate: $checkedConvert('paid_through_date', + (v) => const TimestampConverter().fromJson(v as int)), + willRenew: $checkedConvert('will_renew', (v) => v as bool), + ); + return val; + }, + fieldKeyMap: const { + 'paidThroughDate': 'paid_through_date', + 'willRenew': 'will_renew' + }, + ); + +Map _$SubscriptionToJson(Subscription instance) => + { + 'cost': instance.cost, + 'paid_through_date': + const TimestampConverter().toJson(instance.paidThroughDate), + 'will_renew': instance.willRenew, + }; diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.dart index 1fb290348..9dbb53ea4 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.dart @@ -1,4 +1,5 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:shorebird_code_push_protocol/src/models/subscription.dart'; part 'user.g.dart'; @@ -13,6 +14,7 @@ class User { required this.email, this.hasActiveSubscription = false, this.displayName, + this.subscription, }); /// Converts a Map to a [User] @@ -31,5 +33,9 @@ class User { final String? displayName; /// Whether the user is currently a paying customer. + /// TODO(bryanoltman): make this a computed property (subscription?.isActive ?? false). final bool hasActiveSubscription; + + /// The user's current subscription, if any. + final Subscription? subscription; } diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart index f87781dae..f81fc4130 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart @@ -18,6 +18,11 @@ User _$UserFromJson(Map json) => $checkedCreate( hasActiveSubscription: $checkedConvert( 'has_active_subscription', (v) => v as bool? ?? false), displayName: $checkedConvert('display_name', (v) => v as String?), + subscription: $checkedConvert( + 'subscription', + (v) => v == null + ? null + : Subscription.fromJson(v as Map)), ); return val; }, @@ -32,4 +37,5 @@ Map _$UserToJson(User instance) => { 'email': instance.email, 'display_name': instance.displayName, 'has_active_subscription': instance.hasActiveSubscription, + 'subscription': instance.subscription?.toJson(), }; From 54d5b9a7fac1520108ed1f38e08cc90008ed0e16 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Thu, 20 Apr 2023 16:35:47 -0400 Subject: [PATCH 2/5] Add test for subscription --- .../lib/src/models/subscription.dart | 2 +- .../lib/src/models/user.dart | 1 - .../test/src/models/subscription_test.dart | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart diff --git a/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart b/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart index 4243558d3..1daf06fc4 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/subscription.dart @@ -4,7 +4,7 @@ import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; part 'subscription.g.dart'; /// {@template subscription} -/// TODO +/// A user's Shorebird subscription. /// {@endtemplate} @JsonSerializable() class Subscription { diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.dart index 9dbb53ea4..da9eeffd7 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.dart @@ -33,7 +33,6 @@ class User { final String? displayName; /// Whether the user is currently a paying customer. - /// TODO(bryanoltman): make this a computed property (subscription?.isActive ?? false). final bool hasActiveSubscription; /// The user's current subscription, if any. diff --git a/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart new file mode 100644 index 000000000..cea69f906 --- /dev/null +++ b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart @@ -0,0 +1,18 @@ +import 'package:shorebird_code_push_protocol/src/models/models.dart'; +import 'package:test/test.dart'; + +void main() { + group(Subscription, () { + test('can be (de)serialized', () { + final subscription = Subscription( + cost: 100, + paidThroughDate: DateTime.now(), + willRenew: true, + ); + expect( + Subscription.fromJson(subscription.toJson()).toJson(), + equals(subscription.toJson()), + ); + }); + }); +} From 02eece5ff3a2f4c628db2c67c6040ce9dd5c5d4e Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Thu, 20 Apr 2023 16:42:19 -0400 Subject: [PATCH 3/5] Coverage --- .../test/src/models/subscription_test.dart | 20 +++++++++++++++++++ .../test/src/models/user_test.dart | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart index cea69f906..fe670b9bb 100644 --- a/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart +++ b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart @@ -14,5 +14,25 @@ void main() { equals(subscription.toJson()), ); }); + + group('isActive', () { + test('returns true if paidThroughDate is in the future', () { + final subscription = Subscription( + cost: 100, + paidThroughDate: DateTime.now().add(const Duration(days: 1)), + willRenew: true, + ); + expect(subscription.isActive, isTrue); + }); + + test('returns false if paidThroughDate is in the past', () { + final subscription = Subscription( + cost: 100, + paidThroughDate: DateTime.now().subtract(const Duration(days: 1)), + willRenew: true, + ); + expect(subscription.isActive, isFalse); + }); + }); }); } diff --git a/packages/shorebird_code_push_protocol/test/src/models/user_test.dart b/packages/shorebird_code_push_protocol/test/src/models/user_test.dart index 67d8e04f0..a3d8e7b2c 100644 --- a/packages/shorebird_code_push_protocol/test/src/models/user_test.dart +++ b/packages/shorebird_code_push_protocol/test/src/models/user_test.dart @@ -4,7 +4,15 @@ import 'package:test/test.dart'; void main() { group('User', () { test('can be (de)serialized', () { - const user = User(id: 1, email: 'test@shorebird.dev'); + final user = User( + id: 1, + email: 'test@shorebird.dev', + subscription: Subscription( + cost: 100, + paidThroughDate: DateTime.now(), + willRenew: true, + ), + ); expect( User.fromJson(user.toJson()).toJson(), equals(user.toJson()), From cc0c66ee8dfdb2d3a51b47038e3f68e688d33079 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Mon, 24 Apr 2023 11:10:37 -0400 Subject: [PATCH 4/5] Remove subscription from user --- .../shorebird_code_push_protocol/lib/src/models/user.dart | 4 ---- .../lib/src/models/user.g.dart | 6 ------ .../test/src/models/user_test.dart | 7 +------ 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.dart index da9eeffd7..3ed0621bc 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.dart @@ -14,7 +14,6 @@ class User { required this.email, this.hasActiveSubscription = false, this.displayName, - this.subscription, }); /// Converts a Map to a [User] @@ -34,7 +33,4 @@ class User { /// Whether the user is currently a paying customer. final bool hasActiveSubscription; - - /// The user's current subscription, if any. - final Subscription? subscription; } diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart index f81fc4130..f87781dae 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.g.dart @@ -18,11 +18,6 @@ User _$UserFromJson(Map json) => $checkedCreate( hasActiveSubscription: $checkedConvert( 'has_active_subscription', (v) => v as bool? ?? false), displayName: $checkedConvert('display_name', (v) => v as String?), - subscription: $checkedConvert( - 'subscription', - (v) => v == null - ? null - : Subscription.fromJson(v as Map)), ); return val; }, @@ -37,5 +32,4 @@ Map _$UserToJson(User instance) => { 'email': instance.email, 'display_name': instance.displayName, 'has_active_subscription': instance.hasActiveSubscription, - 'subscription': instance.subscription?.toJson(), }; diff --git a/packages/shorebird_code_push_protocol/test/src/models/user_test.dart b/packages/shorebird_code_push_protocol/test/src/models/user_test.dart index a3d8e7b2c..6b7704f8d 100644 --- a/packages/shorebird_code_push_protocol/test/src/models/user_test.dart +++ b/packages/shorebird_code_push_protocol/test/src/models/user_test.dart @@ -4,14 +4,9 @@ import 'package:test/test.dart'; void main() { group('User', () { test('can be (de)serialized', () { - final user = User( + const user = User( id: 1, email: 'test@shorebird.dev', - subscription: Subscription( - cost: 100, - paidThroughDate: DateTime.now(), - willRenew: true, - ), ); expect( User.fromJson(user.toJson()).toJson(), From 41387353c86d13eadf04fcede07cedd0b0186f3e Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Mon, 24 Apr 2023 11:28:33 -0400 Subject: [PATCH 5/5] feedback --- packages/shorebird_code_push_protocol/lib/src/models/user.dart | 1 - .../test/src/models/subscription_test.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/shorebird_code_push_protocol/lib/src/models/user.dart b/packages/shorebird_code_push_protocol/lib/src/models/user.dart index 3ed0621bc..1fb290348 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/user.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/user.dart @@ -1,5 +1,4 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:shorebird_code_push_protocol/src/models/subscription.dart'; part 'user.g.dart'; diff --git a/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart index fe670b9bb..bc30aa11e 100644 --- a/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart +++ b/packages/shorebird_code_push_protocol/test/src/models/subscription_test.dart @@ -1,4 +1,4 @@ -import 'package:shorebird_code_push_protocol/src/models/models.dart'; +import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; import 'package:test/test.dart'; void main() {