From c2a76c11f0b812985a7f6bcd37fc23d4df6b0e14 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 10 Oct 2023 15:06:55 -0300 Subject: [PATCH 1/2] Fix the bug observed in the integration attempt The product SKUs seen in debug show either `IsSubscription` or `IsInUserCollection` properties ON. Never both. So, I'm relaxing the first property in favor of the second, when computing the expiration date. --- storeapi/base/impl/StoreContext.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/storeapi/base/impl/StoreContext.cpp b/storeapi/base/impl/StoreContext.cpp index 2a5f60077..d3f0954e8 100644 --- a/storeapi/base/impl/StoreContext.cpp +++ b/storeapi/base/impl/StoreContext.cpp @@ -38,9 +38,11 @@ winrt::hstring sha256(winrt::hstring input); std::chrono::system_clock::time_point StoreContext::Product::CurrentExpirationDate() const { - // A single product might have more than one SKU. + // A single product might have more than one SKU and not all of them + // (maybe none) show both `IsSubscription` and `IsInUserCollection` properties + // simultaneously true. for (auto sku : self.Skus()) { - if (sku.IsInUserCollection() && sku.IsSubscription()) { + if (sku.IsInUserCollection()) { auto collected = sku.CollectionData(); return winrt::clock::to_sys(collected.EndDate()); } From e57afb0e4f63389ddd2845c9602407981310020f Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 10 Oct 2023 15:11:10 -0300 Subject: [PATCH 2/2] Ensures the max end date if user has more than 1 sku The previous fix raised a concern on whether the user will endup having multiple SKUs of the same product. If so, multiple end dates would be found, but the iteration stopped on the first collected SKU. This ensures we go over them all, returning the last end date found. --- storeapi/base/impl/StoreContext.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/storeapi/base/impl/StoreContext.cpp b/storeapi/base/impl/StoreContext.cpp index d3f0954e8..0d155b4f4 100644 --- a/storeapi/base/impl/StoreContext.cpp +++ b/storeapi/base/impl/StoreContext.cpp @@ -10,9 +10,11 @@ #include #include +#include #include #include #include +#include #include #include "../Exception.hpp" @@ -41,18 +43,22 @@ StoreContext::Product::CurrentExpirationDate() const { // A single product might have more than one SKU and not all of them // (maybe none) show both `IsSubscription` and `IsInUserCollection` properties // simultaneously true. - for (auto sku : self.Skus()) { - if (sku.IsInUserCollection()) { - auto collected = sku.CollectionData(); - return winrt::clock::to_sys(collected.EndDate()); - } + auto expDates = self.Skus() | + std::views::filter(&StoreSku::IsInUserCollection) | + std::views::transform([](StoreSku const& s) { + return s.CollectionData().EndDate(); + }); + auto endWinDate = std::ranges::max_element(expDates); + + // Should never be true if called from a product the user is subscribed to. + if (expDates.empty()) { + throw Exception{ + ErrorCode::Unsubscribed, + std::format("product ID: {}", winrt::to_string(self.StoreId())), + }; } - // Should be unreachable if called from a product user is subscribed to. - throw Exception{ - ErrorCode::Unsubscribed, - std::format("product ID: {}", winrt::to_string(self.StoreId())), - }; + return winrt::clock::to_sys(*endWinDate); } void StoreContext::Product::PromptUserForPurchase(