stuff
Some checks are pending
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
339bbaae2d
commit
fface20519
10 changed files with 65 additions and 85 deletions
|
|
@ -5,15 +5,15 @@ void main() {
|
|||
group('ApiConfigV2 voice endpoints', () {
|
||||
test('builds pack card voices path', () {
|
||||
expect(
|
||||
ApiConfigV2.packCardVoices('123', 45),
|
||||
ApiConfigV2.packCardVoices('123', '45'),
|
||||
'/packs/123/cards/45/voices',
|
||||
);
|
||||
});
|
||||
|
||||
test('builds voice file path and url', () {
|
||||
expect(ApiConfigV2.voiceFile(7), '/voice/7');
|
||||
expect(ApiConfigV2.voiceFile('7'), '/voice/7');
|
||||
|
||||
final voiceUrl = ApiConfigV2.getVoiceFileUrl(7);
|
||||
final voiceUrl = ApiConfigV2.getVoiceFileUrl('7');
|
||||
expect(voiceUrl, contains('/api/v2/voice/7'));
|
||||
expect(voiceUrl.startsWith('http'), isTrue);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,21 +93,15 @@ void main() {
|
|||
test('creates request correctly', () {
|
||||
final request = CreateChatSessionRequest(
|
||||
title: 'New Chat Session',
|
||||
description: 'A new chat',
|
||||
tags: ['ai', 'assistant'],
|
||||
);
|
||||
|
||||
expect(request.title, 'New Chat Session');
|
||||
expect(request.description, 'A new chat');
|
||||
expect(request.tags, ['ai', 'assistant']);
|
||||
});
|
||||
|
||||
test('supports optional fields', () {
|
||||
final request = CreateChatSessionRequest(title: 'Simple Chat');
|
||||
|
||||
expect(request.title, 'Simple Chat');
|
||||
expect(request.description, isNull);
|
||||
expect(request.tags, isEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -164,8 +158,6 @@ void main() {
|
|||
test('CreateChatSessionRequest serializes and deserializes correctly', () {
|
||||
final request = CreateChatSessionRequest(
|
||||
title: 'New Session',
|
||||
description: 'Description',
|
||||
tags: ['tag1', 'tag2'],
|
||||
);
|
||||
|
||||
final json = request.toJson();
|
||||
|
|
@ -230,20 +222,14 @@ void main() {
|
|||
test('CreateChatSessionRequest equality works correctly', () {
|
||||
final request1 = CreateChatSessionRequest(
|
||||
title: 'Test',
|
||||
description: 'Desc',
|
||||
tags: ['tag'],
|
||||
);
|
||||
|
||||
final request2 = CreateChatSessionRequest(
|
||||
title: 'Test',
|
||||
description: 'Desc',
|
||||
tags: ['tag'],
|
||||
);
|
||||
|
||||
final request3 = CreateChatSessionRequest(
|
||||
title: 'Different',
|
||||
description: 'Desc',
|
||||
tags: ['tag'],
|
||||
);
|
||||
|
||||
expect(request1, equals(request2));
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ void main() {
|
|||
late AuthService authService;
|
||||
|
||||
const code = '123456';
|
||||
final user = UserDto(id: 1, email: 'user@example.com', name: 'Test User');
|
||||
final user = UserDto(id: '1', email: 'user@example.com', name: 'Test User');
|
||||
final authResponse = AuthResponseV2(
|
||||
user: user,
|
||||
accessToken: 'access',
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ void main() {
|
|||
// Test that the method exists and handles auth errors properly
|
||||
// Actual submission would require backend connectivity and auth
|
||||
final statistics = TestStatisticsDto(
|
||||
testId: 123,
|
||||
testId: 'test-123',
|
||||
words: AllWordsStatisticsDto.empty(),
|
||||
attempts: 1,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ void main() {
|
|||
await stateManager.loadFavorites();
|
||||
|
||||
// Check that loaded state has the favorites
|
||||
expect(stateManager.favorites, {1, 2, 3});
|
||||
expect(stateManager.favorites, {'1', '2', '3'});
|
||||
});
|
||||
|
||||
test('loadFavorites handles empty favorites', () async {
|
||||
|
|
@ -43,53 +43,49 @@ void main() {
|
|||
expect(stateManager.favorites, isEmpty);
|
||||
});
|
||||
|
||||
test('loadFavorites handles invalid IDs', () async {
|
||||
// Set up favorites with invalid ID
|
||||
test('loadFavorites keeps stored IDs as strings', () async {
|
||||
await prefs.setStringList('favorites', ['1', 'invalid', '3']);
|
||||
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
// Should only contain valid IDs
|
||||
expect(stateManager.favorites, {1, 3});
|
||||
expect(stateManager.favorites, {'1', 'invalid', '3'});
|
||||
});
|
||||
|
||||
test('toggleFavorite adds card to favorites', () async {
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
// Toggle a favorite
|
||||
await stateManager.toggleFavorite(5);
|
||||
await stateManager.toggleFavorite('5');
|
||||
|
||||
// Check that card is now favorite
|
||||
expect(stateManager.isFavorite(5), isTrue);
|
||||
expect(stateManager.isFavorite('5'), isTrue);
|
||||
});
|
||||
|
||||
test('toggleFavorite removes card from favorites', () async {
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
// Add a favorite
|
||||
await stateManager.toggleFavorite(5);
|
||||
expect(stateManager.isFavorite(5), isTrue);
|
||||
await stateManager.toggleFavorite('5');
|
||||
expect(stateManager.isFavorite('5'), isTrue);
|
||||
|
||||
// Remove it
|
||||
await stateManager.toggleFavorite(5);
|
||||
expect(stateManager.isFavorite(5), isFalse);
|
||||
await stateManager.toggleFavorite('5');
|
||||
expect(stateManager.isFavorite('5'), isFalse);
|
||||
});
|
||||
|
||||
test('toggleFavorite persists to SharedPreferences', () async {
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
// Toggle a favorite
|
||||
await stateManager.toggleFavorite(7);
|
||||
await stateManager.toggleFavorite('7');
|
||||
|
||||
// Check persistence by reloading
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
expect(stateManager.favorites, {7});
|
||||
expect(stateManager.favorites, {'7'});
|
||||
});
|
||||
|
||||
test('isFavorite returns false for unknown card', () {
|
||||
// Without loading
|
||||
expect(stateManager.isFavorite(1), isFalse);
|
||||
expect(stateManager.isFavorite('1'), isFalse);
|
||||
});
|
||||
|
||||
test('favorites getter returns empty set initially', () {
|
||||
|
|
@ -101,23 +97,23 @@ void main() {
|
|||
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
expect(stateManager.favorites, {10, 20});
|
||||
expect(stateManager.favorites, {'10', '20'});
|
||||
});
|
||||
|
||||
test('multiple toggles work correctly', () async {
|
||||
await stateManager.loadFavorites();
|
||||
|
||||
// Toggle multiple favorites
|
||||
await stateManager.toggleFavorite(1);
|
||||
await stateManager.toggleFavorite(2);
|
||||
await stateManager.toggleFavorite(3);
|
||||
await stateManager.toggleFavorite('1');
|
||||
await stateManager.toggleFavorite('2');
|
||||
await stateManager.toggleFavorite('3');
|
||||
|
||||
expect(stateManager.favorites, {1, 2, 3});
|
||||
expect(stateManager.favorites, {'1', '2', '3'});
|
||||
|
||||
// Remove one
|
||||
await stateManager.toggleFavorite(2);
|
||||
await stateManager.toggleFavorite('2');
|
||||
|
||||
expect(stateManager.favorites, {1, 3});
|
||||
expect(stateManager.favorites, {'1', '3'});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||
import 'package:mnemo_cards_web_v2/domain/models/purchase_models.dart';
|
||||
import 'package:mnemo_cards_web_v2/domain/services/purchases_service.dart';
|
||||
import 'package:mnemo_cards_web_v2/domain/state/purchase_state_manager.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void main() {
|
|||
name: 'Test Game',
|
||||
questions: [
|
||||
SimpleTestQuestionBody(
|
||||
id: 1,
|
||||
id: 'q1',
|
||||
text: 'What is 2+2?',
|
||||
buttons: [
|
||||
TestButtonDto.text('3', '3'),
|
||||
|
|
@ -107,14 +107,14 @@ void main() {
|
|||
name: 'Multi Question Test',
|
||||
questions: [
|
||||
SimpleTestQuestionBody(
|
||||
id: 1,
|
||||
id: 'q1',
|
||||
text: 'Q1?',
|
||||
buttons: [TestButtonDto.text('A', 'A')],
|
||||
answer: 'A',
|
||||
word: 'one',
|
||||
),
|
||||
SimpleTestQuestionBody(
|
||||
id: 2,
|
||||
id: 'q2',
|
||||
text: 'Q2?',
|
||||
buttons: [TestButtonDto.text('B', 'B')],
|
||||
answer: 'B',
|
||||
|
|
|
|||
|
|
@ -33,15 +33,15 @@ void main() {
|
|||
late UserStateManager userStateManager;
|
||||
late SharedPreferences sharedPreferences;
|
||||
|
||||
const testUser = UserDto(
|
||||
final testUser = UserDto(
|
||||
id: 'test-user-123',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
);
|
||||
|
||||
const testPackId = 'pack-abc-123';
|
||||
const testCardId1 = 1;
|
||||
const testCardId2 = 2;
|
||||
const testCardId1 = '1';
|
||||
const testCardId2 = '2';
|
||||
|
||||
setUp(() async {
|
||||
// Initialize SharedPreferences with mock
|
||||
|
|
@ -75,21 +75,21 @@ void main() {
|
|||
expect(userStateManager.state, equals(const UserState.guest()));
|
||||
|
||||
// === STEP 2: Auto-login attempt (no saved token) ===
|
||||
when(mockHttpRepository.isAuthenticated())
|
||||
.thenAnswer((_) async => false);
|
||||
when(() => mockHttpRepository.isAuthenticated()).thenAnswer((_) async => false);
|
||||
|
||||
final autoLoginUser = await authService.autoLogin();
|
||||
expect(autoLoginUser, isNull);
|
||||
|
||||
// === STEP 3: Manual login with Telegram ===
|
||||
const telegramCode = 'telegram-auth-code-123';
|
||||
final authResponse = AuthResponse(
|
||||
final authResponse = AuthResponseV2(
|
||||
user: testUser,
|
||||
accessToken: 'test-access-token',
|
||||
refreshToken: 'test-refresh-token',
|
||||
expiresAt: null,
|
||||
);
|
||||
|
||||
when(mockHttpRepository.authenticateWithTelegram(telegramCode))
|
||||
when(() => mockHttpRepository.authenticateWithTelegram(telegramCode))
|
||||
.thenAnswer((_) async => authResponse);
|
||||
|
||||
final loggedInUser = await authService.loginWithTelegram(telegramCode);
|
||||
|
|
@ -98,8 +98,9 @@ void main() {
|
|||
expect(loggedInUser?.name, equals(testUser.name));
|
||||
|
||||
// Update user state
|
||||
userStateManager.setUser(loggedInUser!);
|
||||
expect(userStateManager.state, equals(UserState.authenticated(testUser)));
|
||||
await userStateManager.setUser(loggedInUser!);
|
||||
expect(userStateManager.isAuthenticated, isTrue);
|
||||
expect(userStateManager.user, equals(testUser));
|
||||
|
||||
// === STEP 4: User starts learning cards ===
|
||||
// Check initial progress
|
||||
|
|
@ -137,8 +138,8 @@ void main() {
|
|||
expect(newPackProgressService.isCardLearned(testPackId, testCardId2), isTrue);
|
||||
|
||||
// === STEP 6: User logs out ===
|
||||
when(mockHttpRepository.logout()).thenAnswer((_) async => {});
|
||||
when(mockHttpRepository.clearTokens()).thenAnswer((_) async => {});
|
||||
when(() => mockHttpRepository.logout()).thenAnswer((_) async {});
|
||||
when(() => mockHttpRepository.clearTokens()).thenAnswer((_) async {});
|
||||
|
||||
await authService.logout();
|
||||
userStateManager.logout();
|
||||
|
|
@ -188,20 +189,20 @@ void main() {
|
|||
|
||||
test('User state transitions are correct', () async {
|
||||
// Start as guest
|
||||
expect(userStateManager.state.isGuest, isTrue);
|
||||
expect(userStateManager.state.isAuthenticated, isFalse);
|
||||
expect(userStateManager.isGuest, isTrue);
|
||||
expect(userStateManager.isAuthenticated, isFalse);
|
||||
|
||||
// Login
|
||||
userStateManager.setUser(testUser);
|
||||
expect(userStateManager.state.isGuest, isFalse);
|
||||
expect(userStateManager.state.isAuthenticated, isTrue);
|
||||
expect(userStateManager.state.user, equals(testUser));
|
||||
await userStateManager.setUser(testUser);
|
||||
expect(userStateManager.isGuest, isFalse);
|
||||
expect(userStateManager.isAuthenticated, isTrue);
|
||||
expect(userStateManager.user, equals(testUser));
|
||||
|
||||
// Logout
|
||||
userStateManager.logout();
|
||||
expect(userStateManager.state.isGuest, isTrue);
|
||||
expect(userStateManager.state.isAuthenticated, isFalse);
|
||||
expect(userStateManager.state.user, isNull);
|
||||
expect(userStateManager.isGuest, isTrue);
|
||||
expect(userStateManager.isAuthenticated, isFalse);
|
||||
expect(userStateManager.user, isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,15 +31,15 @@ void main() {
|
|||
late SharedPreferences sharedPreferences;
|
||||
|
||||
final testUser = UserDto(
|
||||
id: 123,
|
||||
id: '123',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
);
|
||||
|
||||
const testPackId = 'pack-abc-123';
|
||||
const testCardId1 = 1;
|
||||
const testCardId2 = 2;
|
||||
const testCardId3 = 3;
|
||||
const testCardId1 = '1';
|
||||
const testCardId2 = '2';
|
||||
const testCardId3 = '3';
|
||||
|
||||
setUp(() async {
|
||||
// Initialize SharedPreferences with mock
|
||||
|
|
@ -202,26 +202,26 @@ void main() {
|
|||
expect(packProgressService.getPackProgress(packId), equals(0));
|
||||
|
||||
// Learn cards one by one
|
||||
await packProgressService.markCardLearned(packId, 1);
|
||||
await packProgressService.markCardLearned(packId, '1');
|
||||
expect(packProgressService.getPackProgress(packId), equals(1));
|
||||
|
||||
await packProgressService.markCardLearned(packId, 2);
|
||||
await packProgressService.markCardLearned(packId, '2');
|
||||
expect(packProgressService.getPackProgress(packId), equals(2));
|
||||
|
||||
await packProgressService.markCardLearned(packId, 3);
|
||||
await packProgressService.markCardLearned(packId, '3');
|
||||
expect(packProgressService.getPackProgress(packId), equals(3));
|
||||
|
||||
await packProgressService.markCardLearned(packId, 4);
|
||||
await packProgressService.markCardLearned(packId, '4');
|
||||
expect(packProgressService.getPackProgress(packId), equals(4));
|
||||
|
||||
await packProgressService.markCardLearned(packId, 5);
|
||||
await packProgressService.markCardLearned(packId, '5');
|
||||
expect(packProgressService.getPackProgress(packId), equals(5));
|
||||
|
||||
// Verify all cards are learned
|
||||
final learnedCards = packProgressService.getLearnedCards(packId);
|
||||
expect(learnedCards.length, equals(5));
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
expect(packProgressService.isCardLearned(packId, i), isTrue);
|
||||
expect(packProgressService.isCardLearned(packId, '$i'), isTrue);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -15,19 +15,11 @@ class MockHttpRepositoryV2 extends Mock implements HttpRepositoryV2 {}
|
|||
|
||||
class MockUserScopeHolder extends Mock implements UserScopeHolder {}
|
||||
|
||||
class _TestAppScopeHolder extends ScopeHolder<AppScopeContainer> {
|
||||
_TestAppScopeHolder(this._scope);
|
||||
|
||||
final AppScopeContainer _scope;
|
||||
|
||||
@override
|
||||
AppScopeContainer createContainer() => _scope;
|
||||
}
|
||||
|
||||
void main() {
|
||||
late MockAppScopeContainer mockAppScope;
|
||||
late MockHttpRepositoryV2 mockHttpRepository;
|
||||
late MockUserScopeHolder mockUserScopeHolder;
|
||||
late ScopeStateHolder<AppScopeContainer?> appScopeHolder;
|
||||
|
||||
setUp(() {
|
||||
mockAppScope = MockAppScopeContainer();
|
||||
|
|
@ -37,12 +29,16 @@ void main() {
|
|||
when(() => mockAppScope.httpRepository).thenReturn(mockHttpRepository);
|
||||
when(() => mockAppScope.userScopeHolder).thenReturn(mockUserScopeHolder);
|
||||
when(() => mockUserScopeHolder.scope).thenReturn(null);
|
||||
|
||||
appScopeHolder = ScopeStateHolder<AppScopeContainer?>(
|
||||
ScopeState.available(scope: mockAppScope),
|
||||
);
|
||||
});
|
||||
|
||||
Future<void> pumpPackDetails(WidgetTester tester, {required String packId}) {
|
||||
return tester.pumpWidget(
|
||||
ScopeProvider<AppScopeContainer>(
|
||||
holder: _TestAppScopeHolder(mockAppScope),
|
||||
holder: appScopeHolder,
|
||||
child: MaterialApp(
|
||||
home: PackDetailsPage(packId: packId),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue