feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:buzz/features/settings/accent_picker_page.dart';
|
||||
import 'package:buzz/features/settings/theme_picker_page.dart';
|
||||
import 'package:buzz/features/settings/settings_page.dart';
|
||||
import 'package:buzz/shared/theme/theme.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../helpers/widget_helpers.dart';
|
||||
|
||||
Future<SharedPreferences> _prefs(Map<String, Object> initial) async {
|
||||
SharedPreferences.setMockInitialValues(initial);
|
||||
return SharedPreferences.getInstance();
|
||||
}
|
||||
|
||||
Future<void> _pumpPicker(
|
||||
WidgetTester tester,
|
||||
Widget page, {
|
||||
Map<String, Object> prefs = const {},
|
||||
}) async {
|
||||
final instance = await _prefs(prefs);
|
||||
await tester.pumpWidget(
|
||||
WidgetHelpers.testable(
|
||||
child: page,
|
||||
overrides: [savedPrefsProvider.overrideWithValue(instance)],
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> _search(WidgetTester tester, String query) async {
|
||||
await tester.enterText(find.byType(TextField), query);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
void main() {
|
||||
group('ThemePickerPage', () {
|
||||
testWidgets('system mode offers pairs under their stripped label', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpPicker(tester, const ThemePickerPage());
|
||||
|
||||
await _search(tester, 'github');
|
||||
|
||||
// Paired labels drop the brightness token — one row stands for both halves.
|
||||
expect(find.text('Github'), findsOneWidget);
|
||||
expect(find.text('Github Default'), findsOneWidget);
|
||||
expect(find.text('Github Light'), findsNothing);
|
||||
expect(find.text('Github Dark'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('system mode hides themes with no counterpart', (tester) async {
|
||||
await _pumpPicker(tester, const ThemePickerPage());
|
||||
|
||||
// 'snazzy-light' is light but unpaired, so it cannot follow the OS.
|
||||
await _search(tester, 'snazzy');
|
||||
|
||||
expect(find.text('No themes found'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('system mode normalizes a stored unpaired theme', (
|
||||
tester,
|
||||
) async {
|
||||
final instance = await _prefs({'buzz_color_scheme': 'snazzy-light'});
|
||||
await tester.pumpWidget(
|
||||
WidgetHelpers.testable(
|
||||
child: const ThemePickerPage(),
|
||||
overrides: [savedPrefsProvider.overrideWithValue(instance)],
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
instance.getString('buzz_color_scheme'),
|
||||
themeGroups().paired.first.name,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('light mode lists light themes by their full name', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const ThemePickerPage(),
|
||||
prefs: {'buzz_theme_mode': 'light'},
|
||||
);
|
||||
|
||||
await _search(tester, 'github');
|
||||
|
||||
expect(find.text('Github Light'), findsOneWidget);
|
||||
expect(find.text('Github Light Default'), findsOneWidget);
|
||||
expect(find.text('Github Dark'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('light mode includes unpaired light themes', (tester) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const ThemePickerPage(),
|
||||
prefs: {'buzz_theme_mode': 'light'},
|
||||
);
|
||||
|
||||
await _search(tester, 'snazzy');
|
||||
|
||||
expect(find.text('Snazzy Light'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('dark mode lists dark themes only', (tester) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const ThemePickerPage(),
|
||||
prefs: {'buzz_theme_mode': 'dark'},
|
||||
);
|
||||
|
||||
await _search(tester, 'github');
|
||||
|
||||
expect(find.text('Github Dark'), findsOneWidget);
|
||||
expect(find.text('Github Light'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('checks the row matching the stored selection', (tester) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const ThemePickerPage(),
|
||||
prefs: {'buzz_theme_mode': 'light', 'buzz_color_scheme': 'nord'},
|
||||
);
|
||||
|
||||
await _search(tester, 'nord');
|
||||
|
||||
// 'nord' is dark, so Light mode renders its light fallback instead — the
|
||||
// checkmark must follow what is applied, not the raw stored value.
|
||||
expect(find.byIcon(LucideIcons.check), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('either half of a pair checks the same system row', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const ThemePickerPage(),
|
||||
prefs: {'buzz_color_scheme': 'github-dark'},
|
||||
);
|
||||
|
||||
await _search(tester, 'github');
|
||||
|
||||
final checked = tester
|
||||
.widgetList<ListTile>(find.byType(ListTile))
|
||||
.where((tile) => tile.trailing != null);
|
||||
expect(checked, hasLength(1));
|
||||
expect(find.text('Github'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('tapping a theme persists the selection', (tester) async {
|
||||
final instance = await _prefs({'buzz_theme_mode': 'dark'});
|
||||
await tester.pumpWidget(
|
||||
WidgetHelpers.testable(
|
||||
child: const ThemePickerPage(),
|
||||
overrides: [savedPrefsProvider.overrideWithValue(instance)],
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await _search(tester, 'nord');
|
||||
await tester.tap(find.text('Nord'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(instance.getString('buzz_color_scheme'), 'nord');
|
||||
});
|
||||
});
|
||||
|
||||
group('Buzz accent behavior', () {
|
||||
testWidgets('settings hides accent navigation for Buzz', (tester) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
SettingsPage(
|
||||
profileHeader: const SizedBox.shrink(),
|
||||
identityRecoveryPageBuilder: (_) => const SizedBox.shrink(),
|
||||
),
|
||||
prefs: {'buzz_color_scheme': 'buzz', 'buzz_accent_color': 4},
|
||||
);
|
||||
|
||||
expect(find.text('Accent color'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('settings restores accent navigation away from Buzz', (
|
||||
tester,
|
||||
) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
SettingsPage(
|
||||
profileHeader: const SizedBox.shrink(),
|
||||
identityRecoveryPageBuilder: (_) => const SizedBox.shrink(),
|
||||
),
|
||||
prefs: {
|
||||
'buzz_theme_mode': 'light',
|
||||
'buzz_color_scheme': 'github-light',
|
||||
'buzz_accent_color': 4,
|
||||
},
|
||||
);
|
||||
|
||||
expect(find.text('Accent color'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group('AccentPickerPage', () {
|
||||
testWidgets('lists every accent and checks the stored one', (tester) async {
|
||||
await _pumpPicker(
|
||||
tester,
|
||||
const AccentPickerPage(),
|
||||
prefs: {'buzz_accent_color': 2},
|
||||
);
|
||||
|
||||
for (final accent in accentColors) {
|
||||
expect(find.text(accent.name), findsOneWidget);
|
||||
}
|
||||
expect(find.byIcon(LucideIcons.check), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('tapping an accent persists the index', (tester) async {
|
||||
final instance = await _prefs(const <String, Object>{});
|
||||
await tester.pumpWidget(
|
||||
WidgetHelpers.testable(
|
||||
child: const AccentPickerPage(),
|
||||
overrides: [savedPrefsProvider.overrideWithValue(instance)],
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Green'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
instance.getInt('buzz_accent_color'),
|
||||
accentColors.indexWhere((a) => a.name == 'Green'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user