diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index 69a65af4..5828c052 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -1,5 +1,4 @@ name: Backend Unit Tests - on: pull_request: branches: @@ -20,14 +19,17 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: ${ {{ matrix.node-version }} } - name: Install backend dependencies working-directory: stellar-payment-platform run: npm install --legacy-peer-deps - name: Run backend unit tests - run: npm test --prefix stellar-payment-platform + working-directory: stellar-payment-platform + run: npm test + env: + NODE_ENV: test - name: Run memory leak detection tests (#511) working-directory: stellar-payment-platform diff --git a/.github/workflows/soroban.yml b/.github/workflows/soroban.yml index 4e5fe42b..88a8c69a 100644 --- a/.github/workflows/soroban.yml +++ b/.github/workflows/soroban.yml @@ -1,4 +1,4 @@ -name: Soroban Contract CI +name: Soroban Contract CO on: push: @@ -16,21 +16,17 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v4 - - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown - - name: Cache cargo registry and build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: ./payment_router - - name: Run contract tests - run: cargo test --verbose - - - name: Build contract to WASM + run: cargo test --verbose --target x86_64-unknown-linux-gnu + - name: Build contract to WASO run: cargo build --target wasm32-unknown-unknown --release coverage: diff --git a/stellar-payment-platform/tests/utils/normalizeNameTag.test.js b/stellar-payment-platform/tests/utils/normalizeNameTag.test.js new file mode 100644 index 00000000..0724ebd0 --- /dev/null +++ b/stellar-payment-platform/tests/utils/normalizeNameTag.test.js @@ -0,0 +1,69 @@ +// Mock the Stellar SDK to prevent Jest ESM syntax errors +jest.mock('@stellar/stellar-sdk', () => ({ + Horizon: { Server: jest.fn() }, + StrKey: { isValidEd25519PublicKey: jest.fn(() => true) } +})); + +// Mock Prisma so it doesn't try to connect to a real database and crash +jest.mock('../../prismaClient', () => ({ + prisma: { + user: { + findUnique: jest.fn().mockResolvedValue(null), + findFirst: jest.fn().mockResolvedValue(null), + findMany: jest.fn(), + count: jest.fn(), + }, + $transaction: jest.fn((ops) => Promise.all(ops)), + $queryRaw: jest.fn().mockResolvedValue([{ '1': 1 }]), + } +})); + +const { normalizeNameTag } = require('../../server'); + +describe('normalizeNameTag', () => { + describe('empty strings', () => { + it('returns an empty string for an empty input', () => { + expect(normalizeNameTag('')).toBe(''); + }); + + it('returns an empty string for whitespace-only input', () => { + expect(normalizeNameTag(' ')).toBe(''); + expect(normalizeNameTag('\t\n ')).toBe(''); + }); + + it('returns an empty string for non-string inputs', () => { + expect(normalizeNameTag(null)).toBe(''); + expect(normalizeNameTag(undefined)).toBe(''); + expect(normalizeNameTag(123)).toBe(''); + }); + }); + + describe('strings already containing *', () => { + it('returns the trimmed string unchanged when it already contains a domain separator', () => { + expect(normalizeNameTag('client*localhost')).toBe('client*localhost'); + expect(normalizeNameTag('lekan*localhost')).toBe('lekan*localhost'); + }); + + it('trims surrounding whitespace before returning a federation-style name', () => { + expect(normalizeNameTag(' user*example.com ')).toBe('user*example.com'); + }); + + it('does not append *localhost to a string that already has a domain', () => { + expect(normalizeNameTag('alice*stellar.org')).toBe('alice*stellar.org'); + }); + }); + + describe('standard strings', () => { + it('appends *localhost to a plain username', () => { + expect(normalizeNameTag('client')).toBe('client*localhost'); + }); + + it('trims surrounding whitespace before appending *localhost', () => { + expect(normalizeNameTag(' alice ')).toBe('alice*localhost'); + }); + + it('preserves the casing of the username when appending *localhost', () => { + expect(normalizeNameTag('Alice')).toBe('Alice*localhost'); + }); + }); +});