Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PP-12107: Move BinRangeTest from pay-cardid-data #1206

Merged
merged 2 commits into from
May 10, 2024
Merged

Conversation

oswaldquek
Copy link
Contributor

@oswaldquek oswaldquek commented May 8, 2024

Moving BinRangeTest from pay-cardid-data into this repo as the build-and-push-cardid-candidate CI run will copy the real bin ranges files from s3 into src/main/resources/data-sources. Thus the test will run against real card data in a CI build.

To make the test work locally, overlapping ranges in the current test data (in src/main/resources/data-sources) needed to be amended/deleted.

Also removed the long comment in CardIdResourceITest as it claims the usefulness of it's tests isn't clear. On the contrary the test is useful as it verifies the API actually works.

Removed -DskipTests from the Dockerfile as we want to verify the bin ranges don't overlap (via running BinRangesTest) whilst building the Docker image.

@oswaldquek oswaldquek force-pushed the PP-12107 branch 2 times, most recently from a19b1e1 to 34af3f9 Compare May 9, 2024 15:30
Copy link

@DomBelcher DomBelcher left a comment

Choose a reason for hiding this comment

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

A few questions, rather than anything that definitively needs changing

Function<String[], Range<Long>> cardRangeExtractor = entry -> {
Long minCardDigit = BinRangeParser.calculateMinDigitForCardLength(Long.valueOf(entry[1]), CARD_RANGE_LENGTH);
Long maxCardDigit = BinRangeParser.calculateMaxDigitForCardLength(Long.valueOf(entry[2]), CARD_RANGE_LENGTH);
return Range.closed(minCardDigit, maxCardDigit);

Choose a reason for hiding this comment

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

Is there any reason this is a Function object vs. just being a private static method?

Copy link
Contributor Author

@oswaldquek oswaldquek May 9, 2024

Choose a reason for hiding this comment

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

Hmm yeah it could be a private static field, I'll make the change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although, given this is just test code, it doesn't really matter that we're instantiating this cardRangeExtractor on each thread, rather than placing it in memory reserved for private static fields.

Having no overlap ranges is essential to cardid figuring out with confidence if a card is a corporate card or not.
*/
@Test
void verifyNoOverlappingRanges() {

Choose a reason for hiding this comment

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

I think this test doesn't do anything useful? It builds up the RangeSet and the HashMap from the ranges, and checks that every range in the RangeSet is in the HashMap, but that will always be the case, regardless of what the ranges are, because the ranges are added to both at the same time.

Choose a reason for hiding this comment

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

If you wanted to test that none of the ranges overlap, you could do something like

@Test
void verifyNoOverlappingRanges() {
    RangeSet<Long> setOfBinRanges = TreeRangeSet.create();
    List<Range<Long>> overlappingRanges = new ArrayList<>();
    
    worldpayData.forEach(cardRange -> {
        boolean contains = setOfBinRanges.intersects(cardRange);
        if (contains) {
            overlappingRanges.add(cardRange);
        }
        
        setOfBinRanges.add(cardRange);
    });
    discoverData.forEach(cardRange -> {
        boolean contains = setOfBinRanges.intersects(cardRange);
        if (contains) {
            overlappingRanges.add(cardRange);
        }
        
        setOfBinRanges.add(cardRange);
    });
    testCardData.forEach(cardRange -> {
        boolean contains = setOfBinRanges.intersects(cardRange);
        if (contains) {
            overlappingRanges.add(cardRange);
        }
        
        setOfBinRanges.add(cardRange);
    });
    assertThat(overlappingRanges.size(), is(0));
}

although this somewhat mirrors the other tests - it does have the advantage of checking data within a range, not just between ranges

Choose a reason for hiding this comment

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

Digging into the history it seems this test used to be called checkIfNoExistingRangeInHashMap - I'm still not clear on what the point of that test is though?

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 think this test doesn't do anything useful? It builds up the RangeSet and the HashMap from the ranges, and checks that every range in the RangeSet is in the HashMap, but that will always be the case, regardless of what the ranges are, because the ranges are added to both at the same time.

If there are overlapping ranges, RangeSet will adjust the sets of ranges accordingly, and it will mean there will be a difference in the range sets between the RangeSet and HashMap. See how it works at https://guava.dev/releases/23.0/api/docs/com/google/common/collect/RangeSet.html. So I think your suggested code, although arguably clearer in intention, and what is currently here are essentially the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Digging into the history it seems this test used to be called checkIfNoExistingRangeInHashMap - I'm still not clear on what the point of that test is though?

Nat and I weren't clear on what the was checkIfNoExistingRangeInHashMap trying to achieve, so we renamed it verifyNoOverlappingRanges and gave it some javadoc to clarify. See https://github.com/alphagov/pay-cardid-data/pull/68/files#diff-b5d0a0f2d9eca8d9c1aea690c8dce8ab047b489f2d53c34b28987ec6f5bc31a3R56-R65

To make the test work overlapping ranges in the current test data (in
src/main/resources/data-sources) needed to be amended/deleted.

Also removed the long comment in CardIdResourceITest as it claims the
usefulness of it's tests isn't clear. On the contrary the test is useful as it
verifies the API actually works.

Removed `-DskipTests` from the Dockerfile as we want to verify the bin ranges
don't overlap (via running BinRangesTest) whilst building the Docker image.
Copy link

@DomBelcher DomBelcher left a comment

Choose a reason for hiding this comment

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

👍

@oswaldquek oswaldquek merged commit 8a17646 into master May 10, 2024
8 checks passed
@oswaldquek oswaldquek deleted the PP-12107 branch May 10, 2024 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants