Files
TREK/client/tests/unit/native/nativeAmount.test.ts
T
Maurice 52f0fb882f feat(native): redesign the app's first screens around a living landscape
The screens the app ships itself (welcome, plans, address, own server and
the states between) move from the dark card layout to a light design on an
animated aerial landscape drawn by a WebGL shader (native-shell/scenery.ts):
an island, a coastal town, farmland and mountains in one world.

- Welcome: the landscape with the TREK wordmark, three perks in one card,
  "Explore cloud plans" and "I already have a TREK" as two buttons.
- Plans: one tab per plan; choosing one flies the camera to its place,
  further inland with every plan. Each plan reads as a kind of trip, the
  price sits in a card with a monthly/yearly switch and counts to its new
  amount in the store's own format (native-shell/amount.ts), and a yearly
  price shows what it makes a month. Restore purchases, the renewal terms
  and the links stay as the store rules require.
- Address: the address writes itself on a glass card over the landscape;
  free, the password rules and the agreement sit on white cards.
- Own server: the server address on the glass card; a failed check turns
  the card red with what went wrong, proxy sign-in and client certificate
  panels in the same style.
- States: server not reachable, certificate needed, already subscribed,
  setting up (with its steps, then "Arrived") and the slow setup.
- iPad, an unfolded phone and a phone on its side get two columns, the
  landscape beside the content; on a dual-screen device each half takes
  one screen. Arabic and Hebrew mirror through logical sides only.
- The shader caps the pixel ratio at 2, drops to a lower resolution on a
  slow device, stops in the background and is one still frame with
  reduced motion.
- The sign-in and error page bars over a proxy's page (iOS and Android)
  take the same look: a white card and a dark button.
- Plus Jakarta Sans is bundled for the text, with Montserrat standing in
  for Cyrillic; the wordmark fonts and the old preview images are gone.
- New strings in all 28 languages; the keys of the old screens removed.
- The dev sample plans follow the cloud's plans (start, basis, plus, pro).
2026-11-12 14:18:42 +01:00

42 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import { amountIn } from '../../../native-shell/amount';
// FE-NATIVE-AMOUNT-001 to FE-NATIVE-AMOUNT-005
//
// The amount inside a store price string (client/native-shell/amount.ts): read
// as a number, and written again in the same format, so the plan picker can
// count a price up and turn a yearly price into a monthly one in any currency.
describe('native shell price amounts', () => {
it('FE-NATIVE-AMOUNT-001: a euro price with a decimal comma reads and writes back the same way', () => {
const amount = amountIn('4,90 €');
expect(amount?.value).toBe(4.9);
expect(amount?.render(4.9)).toBe('4,90 €');
expect(amount?.render(79 / 12)).toBe('6,58 €');
});
it('FE-NATIVE-AMOUNT-002: a dollar price keeps its sign in front and its decimal point', () => {
const amount = amountIn('$199.00');
expect(amount?.value).toBe(199);
expect(amount?.render(199 / 12)).toBe('$16.58');
});
it('FE-NATIVE-AMOUNT-003: thousands keep their grouping mark', () => {
expect(amountIn('1.290 ₽')?.value).toBe(1290);
expect(amountIn('1.290 ₽')?.render(12345)).toBe('12.345 ₽');
expect(amountIn('CHF 1’290.50')?.value).toBe(1290.5);
expect(amountIn('CHF 1’290.50')?.render(2000)).toBe('CHF 2’000.00');
expect(amountIn("CHF 1'290.50")?.render(2000)).toBe("CHF 2'000.00");
});
it('FE-NATIVE-AMOUNT-004: a price without figures has no amount', () => {
expect(amountIn('')).toBeNull();
expect(amountIn('Free')).toBeNull();
});
it('FE-NATIVE-AMOUNT-005: a count never runs below zero', () => {
expect(amountIn('4,90 €')?.render(-3)).toBe('0,00 €');
});
});