🔍 Code Extractor

class TestAUValidator

Maturity: 50

Unit test class for validating the AUValidator class, which validates Australian invoice extraction results including ABN, GST, banking details, and tax invoice requirements.

File:
/tf/active/vicechatdev/invoice_extraction/tests/test_validators.py
Lines:
485 - 644
Complexity:
moderate

Purpose

This test class provides comprehensive test coverage for the AUValidator class, ensuring it correctly validates Australian-specific invoice fields such as ABN (Australian Business Number), GST calculations, BSB/account numbers, Australian addresses, AUD currency, and tax invoice requirements. It tests both valid and invalid scenarios, verifying that critical errors are flagged as invalid and non-critical issues generate warnings.

Source Code

class TestAUValidator(unittest.TestCase):
    """Test cases for the AUValidator class."""
    
    def setUp(self):
        """Set up test environment before each test."""
        self.config = {
            'required_fields': {
                'invoice.number': 'critical',
                'vendor.name': 'critical',
                'amounts.total': 'critical'
            },
            'au_gst_rate': 10.0
        }
        self.validator = AUValidator(self.config)
        
        # Sample valid Australian extraction result
        self.valid_au_extraction = {
            'invoice': {
                'number': 'INV-12345',
                'issue_date': '2023-01-15',
                'due_date': '2023-02-15'
            },
            'vendor': {
                'name': 'Australian Test Pty Ltd',
                'address': '123 Sydney Road, Sydney NSW 2000, Australia',
                'abn': '12 345 678 901'
            },
            'amounts': {
                'subtotal': 500.00,
                'gst': 50.00,
                'total': 550.00,
                'gst_rate': 10,
                'currency': 'AUD'
            },
            'payment': {
                'bsb': '062-000',
                'account_number': '12345678'
            }
        }
    
    def test_validate_au_extraction(self):
        """Test validation of a valid Australian extraction result."""
        result = self.validator.validate(self.valid_au_extraction)
        self.assertTrue(result.is_valid)
        self.assertEqual(len(result.issues), 0)
    
    def test_validate_abn(self):
        """Test validation of Australian Business Number."""
        # Test invalid ABN format
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['vendor'] = {
            'name': 'Australian Test Pty Ltd',
            'address': '123 Sydney Road, Sydney NSW 2000, Australia',
            'abn': '1234567890'  # Too short (should be 11 digits)
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertFalse(result.is_valid)  # ABN is critical in Australia
        self.assertGreaterEqual(len(result.issues), 1)
        
        # Test invalid ABN checksum
        invalid_extraction['vendor']['abn'] = '11 111 111 111'  # Invalid checksum
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Checksum is a warning, not an error
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_au_address(self):
        """Test validation of Australian address."""
        # Test non-Australian address
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['vendor'] = {
            'name': 'Australian Test Pty Ltd',
            'address': '123 Main St, London, W1A 1AA, UK',  # Not Australian address
            'abn': '12 345 678 901'
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Address is a warning, not error
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_gst_rate(self):
        """Test validation of Australian GST rate."""
        # Test invalid GST rate
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['amounts']['gst_rate'] = 15  # Not standard Australian rate
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # GST rate is a warning, not error
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_au_banking_details(self):
        """Test validation of Australian banking details."""
        # Test invalid BSB
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['payment'] = {
            'bsb': '06200',  # Wrong format
            'account_number': '12345678'
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Banking details are warnings, not errors
        self.assertGreaterEqual(len(result.warnings), 1)
        
        # Test invalid account number
        invalid_extraction['payment'] = {
            'bsb': '062-000',
            'account_number': '123'  # Too short
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Banking details are warnings, not errors
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_au_currency(self):
        """Test validation of Australian currency."""
        # Test non-AUD currency
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['amounts']['currency'] = 'USD'  # Not AUD
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Currency is a warning, not error
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_gst_calculation(self):
        """Test validation of GST calculation."""
        # Test inconsistent GST calculation
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['amounts'] = {
            'subtotal': 500.00,
            'gst': 60.00,  # Should be 50.00 (10% of 500)
            'total': 560.00,
            'gst_rate': 10,
            'currency': 'AUD'
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertTrue(result.is_valid)  # Calculation issues are warnings, not errors
        self.assertGreaterEqual(len(result.warnings), 1)
    
    def test_validate_tax_invoice_requirements(self):
        """Test validation of Australian tax invoice requirements."""
        # Test missing ABN (mandatory in Australia)
        invalid_extraction = self.valid_au_extraction.copy()
        invalid_extraction['vendor'] = {
            'name': 'Australian Test Pty Ltd',
            'address': '123 Sydney Road, Sydney NSW 2000, Australia'
            # Missing ABN
        }
        
        result = self.validator.validate(invalid_extraction)
        self.assertFalse(result.is_valid)
        self.assertGreaterEqual(len(result.issues), 1)
        
        # Test large invoice without recipient (required for invoices over $1000)
        large_invoice = self.valid_au_extraction.copy()
        large_invoice['amounts']['total'] = 1500.00  # Over $1000
        
        result = self.validator.validate(large_invoice)
        self.assertTrue(result.is_valid)  # Missing recipient is a warning, not error
        self.assertGreaterEqual(len(result.warnings), 1)

Parameters

Name Type Default Kind
bases unittest.TestCase -

Parameter Details

bases: Inherits from unittest.TestCase to provide testing framework functionality including assertions, test discovery, and test execution capabilities

Return Value

As a test class, it does not return values directly. Each test method performs assertions that either pass or fail. Test methods validate that the AUValidator.validate() method returns ValidationResult objects with appropriate is_valid flags, issues lists, and warnings lists.

Class Interface

Methods

setUp(self) -> None

Purpose: Initialize test environment before each test method runs, creating validator instance and sample data

Returns: None - sets up instance attributes self.config, self.validator, and self.valid_au_extraction

test_validate_au_extraction(self) -> None

Purpose: Test that a valid Australian invoice extraction passes validation without errors or warnings

Returns: None - asserts that validation result is valid with zero issues

test_validate_abn(self) -> None

Purpose: Test ABN validation including format validation (critical) and checksum validation (warning)

Returns: None - asserts that invalid ABN format fails validation and invalid checksum generates warning

test_validate_au_address(self) -> None

Purpose: Test that non-Australian addresses generate warnings but do not fail validation

Returns: None - asserts that non-AU address is valid but generates at least one warning

test_validate_gst_rate(self) -> None

Purpose: Test that non-standard GST rates (not 10%) generate warnings but do not fail validation

Returns: None - asserts that invalid GST rate is valid but generates at least one warning

test_validate_au_banking_details(self) -> None

Purpose: Test validation of Australian BSB and account number formats, ensuring invalid formats generate warnings

Returns: None - asserts that invalid BSB or account number is valid but generates warnings

test_validate_au_currency(self) -> None

Purpose: Test that non-AUD currency generates a warning but does not fail validation

Returns: None - asserts that non-AUD currency is valid but generates at least one warning

test_validate_gst_calculation(self) -> None

Purpose: Test that incorrect GST calculations (GST != subtotal * 10%) generate warnings

Returns: None - asserts that incorrect GST calculation is valid but generates at least one warning

test_validate_tax_invoice_requirements(self) -> None

Purpose: Test Australian tax invoice requirements including mandatory ABN and recipient details for large invoices

Returns: None - asserts that missing ABN fails validation and missing recipient on large invoice generates warning

Attributes

Name Type Description Scope
config dict Configuration dictionary containing required_fields and au_gst_rate settings for the validator instance
validator AUValidator Instance of AUValidator class being tested, initialized with self.config instance
valid_au_extraction dict Sample valid Australian invoice extraction result containing invoice, vendor, amounts, and payment details instance

Dependencies

  • unittest
  • datetime
  • logging
  • validators.base_validator
  • validators.uk_validator
  • validators.be_validator
  • validators.au_validator

Required Imports

import unittest
from datetime import datetime
import logging
from validators.base_validator import BaseValidator
from validators.base_validator import ValidationResult
from validators.uk_validator import UKValidator
from validators.be_validator import BEValidator
from validators.au_validator import AUValidator

Usage Example

import unittest
from validators.au_validator import AUValidator

# Run a specific test
if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestAUValidator)
    unittest.TextTestRunner(verbosity=2).run(suite)

# Or run individual test
test = TestAUValidator()
test.setUp()
test.test_validate_au_extraction()

# Or use pytest
# pytest test_au_validator.py::TestAUValidator::test_validate_abn

Best Practices

  • Always call setUp() before running individual tests to initialize the test environment
  • Each test method is independent and tests a specific validation scenario
  • Tests follow the Arrange-Act-Assert pattern: setup data, call validator, assert results
  • Use copy() when modifying test data to avoid affecting other tests
  • Critical validation failures should set is_valid to False, while non-critical issues should only add warnings
  • Run tests using unittest discovery: python -m unittest discover
  • Tests verify both positive (valid data) and negative (invalid data) scenarios
  • ABN validation distinguishes between format errors (critical) and checksum errors (warnings)
  • Large invoices (>$1000 AUD) have additional validation requirements

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class TestAUExtractor 87.1% similar

    Unit test class for testing the AUExtractor class, which extracts data from Australian invoices including ABN, GST, and payment details.

    From: /tf/active/vicechatdev/invoice_extraction/tests/test_extractors.py
  • class AUValidator 86.1% similar

    Australia-specific invoice data validator that extends BaseValidator to implement validation rules for Australian invoices including ABN validation, GST calculations, and Australian tax invoice requirements.

    From: /tf/active/vicechatdev/invoice_extraction/validators/au_validator.py
  • class TestUKValidator 78.5% similar

    Unit test class for validating the UKValidator class functionality, testing UK-specific invoice validation rules including VAT numbers, addresses, banking details, and currency.

    From: /tf/active/vicechatdev/invoice_extraction/tests/test_validators.py
  • class TestBEValidator 73.0% similar

    Unit test class for validating the BEValidator class, which validates Belgian invoice extraction results including VAT numbers, addresses, IBAN, currency, and legal requirements.

    From: /tf/active/vicechatdev/invoice_extraction/tests/test_validators.py
  • class AUExtractor 70.3% similar

    Australia-specific invoice data extractor that uses LLM (Large Language Model) to extract structured invoice data from Australian tax invoices, handling ABN, ACN, GST, BSB numbers and Australian date formats.

    From: /tf/active/vicechatdev/invoice_extraction/extractors/au_extractor.py
← Back to Browse