Skip to content

Conversation

@iamgabrielma
Copy link
Contributor

@iamgabrielma iamgabrielma commented Sep 3, 2025

Closes WOOMOB-1255

Description

This PR mocks the now date to a fixed date so we avoid flakiness on test_isExpired_when_current_date_then_returns_true.

I'm not convinced of the value of the test, since in the implementation of POSCoupon we check the expiration against Date(), so a 2nd option could be to just pass "now" as "a few seconds ago" or similar, which should be closer to the real implementation.

We cannot use the fixed date either in the tests that check for future dates, otherwise sooner or later the fixed date passed in, will not surpass the actual date of comparison, failing the test (ie: future date as tomorrow in 2024, is still < Date() ).

As a 3rd option, we could change the details of POSCoupon, but I don't see a good reason to change the interface only because of tests.

Let me know what you think, I might lean to option 2 instead, where "now" is actually a couple of seconds ago, rather than using a fixed date.

Testing information

  • CI should pass.

@dangermattic
Copy link
Collaborator

dangermattic commented Sep 3, 2025

1 Warning
⚠️ This PR is assigned to the milestone 23.2. This milestone is due in less than 2 days.
Please make sure to get it merged by then or assign it to a milestone with a later deadline.

Generated by 🚫 Danger

import Foundation
import WooFoundation
import struct Alamofire.JSONEncoding
import struct NetworkingCore.JetpackSite
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot compile the test target unless I add this import, which seems to come from a missing rake generate somewhere else.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest commit in trunk doesn't have this import and passed CI though, could it be from packages not being fully resolved / a need to build the app before tests / a need for a clean build?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried removing this line, building the app then ran POSCouponTests, both the app and tests ran. I've had frustrating times when it took a few tries rebuilding/cleaning though. If you get to build and run tests without this line, let's remove this.

@iamgabrielma iamgabrielma marked this pull request as ready for review September 3, 2025 07:47
@iamgabrielma iamgabrielma added type: task An internally driven task. feature: coupons Related to basic fulfillment such as order tracking. feature: POS Bug labels Sep 3, 2025
@iamgabrielma iamgabrielma added this to the 23.2 milestone Sep 3, 2025
@wpmobilebot
Copy link
Collaborator

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Numberpr16074-5d92305
Version23.1
Bundle IDcom.automattic.alpha.woocommerce
Commit5d92305
Installation URL36n1pvqvnc1go
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@iamgabrielma iamgabrielma requested a review from jaclync September 3, 2025 08:09
Copy link
Contributor

@jaclync jaclync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, lemme know what you think!

@Test func test_isExpired_when_current_date_then_returns_true() {
// Given
let now = Date()
let now = fixedDate(daysFromReference: 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a previous date for dateExpires while isExpired is comparing against Date() makes it not exactly fit the goal of the test case test_isExpired_when_current_date_then_returns_true, which is when the expiration date is the same as the current date.

A common approach is to mock the Date() in the code we're testing. e.g. from the existing POSCoupon.isExpired:

public var isExpired: Bool {
guard let dateExpires = dateExpires else {
return false
}
return dateExpires < Date()
}

to be a function that takes in currentDate: Date = Date():

public func isExpired(currentDate: Date = Date()) -> Bool {
    guard let dateExpires else {
        return false
    }
    return dateExpires < currentDate
}

This way, we can pass any date values for the current date and expiration date.

Also, from the logic, wouldn't isExpired return false when the current date and dateExpires are the same? 🤔 Like it expires right on the expiration date, which sounds like the expected behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way, we can pass any date values for the current date and expiration date.

Yes, so my point with "As a 3rd option, we could change the details of POSCoupon, but I don't see a good reason to change the interface only because of tests." is:

If we would change the isExpired computed var to be a function that might expect a date to be passed in there should be a reason that is not testing only, right? Since we never pass any date in the implementation, nor is expected, my first gut check was that it shouldn't be a function neither accept a date as param, as this change to the implementation would be only for the sake of tests. So should we actually make the change?

I'm happy with making the change if you feel is worth it, just questioning in case this comes up again on a different place with a similar shape 🤔 otherwise might be better to just remove it.

Copy link
Contributor

@joshheald joshheald Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 I hadn't seen this PR, but fixed this in a simpler way...

WDYT about just making it return dateExpires <= Date()? That makes it match the existing tests without changing any interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Josh! Let's go ahead with your PR, its more correct to treat them as expired as soon as the date is equal to expiration, fixing the flakiness as well. I'll mark this one as closed.

import Foundation
import WooFoundation
import struct Alamofire.JSONEncoding
import struct NetworkingCore.JetpackSite
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest commit in trunk doesn't have this import and passed CI though, could it be from packages not being fully resolved / a need to build the app before tests / a need for a clean build?

import Foundation
import WooFoundation
import struct Alamofire.JSONEncoding
import struct NetworkingCore.JetpackSite
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried removing this line, building the app then ran POSCouponTests, both the app and tests ran. I've had frustrating times when it took a few tries rebuilding/cleaning though. If you get to build and run tests without this line, let's remove this.

@iamgabrielma
Copy link
Contributor Author

I've had frustrating times when it took a few tries rebuilding/cleaning though. If you get to build and run tests without this line, let's remove this

Yeah, for some reason it took a couple of clean/rebuilds to make it work 😅, I'll revert it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug feature: coupons Related to basic fulfillment such as order tracking. feature: POS type: task An internally driven task.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants