Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 107 additions & 3 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.3.0"
antlr4:
dependency: transitive
description:
name: antlr4
sha256: "752b4a6e4ad97953652a2b2bbf5377f46c94b579d3372b50080c7e5858234a05"
url: "https://pub.dev"
source: hosted
version: "4.13.2"
args:
dependency: transitive
description:
Expand Down Expand Up @@ -49,6 +57,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
cel:
dependency: transitive
description:
name: cel
sha256: "51d77e16424d41b5fdb0a239be4c8a0550d4dd3f952801d35375ddd90cfb49da"
url: "https://pub.dev"
source: hosted
version: "0.5.4+1"
characters:
dependency: transitive
description:
Expand Down Expand Up @@ -121,6 +137,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.1"
convert:
dependency: transitive
description:
name: convert
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
url: "https://pub.dev"
source: hosted
version: "3.1.2"
cross_file:
dependency: transitive
description:
Expand All @@ -145,6 +169,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.8"
dart_jsonwebtoken:
dependency: transitive
description:
name: dart_jsonwebtoken
sha256: cb79ed79baa02b4f59a597bf365873cbd83f9bb15273d63f7803802d21717c7d
url: "https://pub.dev"
source: hosted
version: "3.4.0"
equatable:
dependency: "direct main"
description:
Expand All @@ -161,6 +193,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.3"
fake_cloud_firestore:
dependency: "direct dev"
description:
name: fake_cloud_firestore
sha256: "95e01c95f956b31c62cb9fc54b8d51f32f1ae2909e6c0a5ce316da997e83a5c4"
url: "https://pub.dev"
source: hosted
version: "4.1.0+1"
fake_firebase_security_rules:
dependency: transitive
description:
name: fake_firebase_security_rules
sha256: "6af54bedfd6985451a9735f2cfac91ffe0128bfc92bf15e8544cd56c6941d6cc"
url: "https://pub.dev"
source: hosted
version: "0.5.4"
ffi:
dependency: transitive
description:
Expand Down Expand Up @@ -273,6 +321,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.3.0"
firebase_auth_mocks:
dependency: "direct dev"
description:
name: firebase_auth_mocks
sha256: ee1076150ea51d181ae24d5f8e2686a1926b7cc54e25c0deaa8ac58705025551
url: "https://pub.dev"
source: hosted
version: "0.15.1"
firebase_auth_platform_interface:
dependency: transitive
description:
Expand All @@ -298,7 +354,7 @@ packages:
source: hosted
version: "4.6.0"
firebase_core_platform_interface:
dependency: transitive
dependency: "direct dev"
description:
name: firebase_core_platform_interface
sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce"
Expand Down Expand Up @@ -608,6 +664,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
logger:
dependency: transitive
description:
name: logger
sha256: "25aee487596a6257655a1e091ec2ae66bc30e7af663592cc3a27e6591e05035c"
url: "https://pub.dev"
source: hosted
version: "2.7.0"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -640,6 +712,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
mock_exceptions:
dependency: transitive
description:
name: mock_exceptions
sha256: "6e3e623712d2c6106ffe9e14732912522b565ddaa82a8dcee6cd4441b5984056"
url: "https://pub.dev"
source: hosted
version: "0.8.2"
more:
dependency: transitive
description:
name: more
sha256: e252628d2183cc09539b686abfbd9d8302675959b89a2a8146f5f4baca6ac5ba
url: "https://pub.dev"
source: hosted
version: "4.7.0"
nested:
dependency: transitive
description:
Expand Down Expand Up @@ -736,6 +824,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "92aa3841d083cc4b0f4709b5c74fd6409a3e6ba833ffc7dc6a8fee096366acf5"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
provider:
dependency: transitive
description:
Expand All @@ -744,14 +840,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.1.5+1"
rx:
dependency: transitive
description:
name: rx
sha256: "7f54bd39cc63a01c770c1de4b6ce8e135eb13119614cba2216bd9a93ccd29e56"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
rxdart:
dependency: "direct main"
description:
name: rxdart
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
url: "https://pub.dev"
source: hosted
version: "0.27.7"
version: "0.28.0"
shared_preferences:
dependency: "direct main"
description:
Expand Down
5 changes: 4 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies:
equatable: ^2.0.5
meta: ^1.8.0
font_awesome_flutter: ^10.2.1
rxdart: ^0.27.5
rxdart: ^0.28.0
animated_text_kit: ^4.2.2
shared_preferences: ^2.2.2
google_fonts: ^6.2.1
Expand All @@ -48,6 +48,9 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
firebase_core_platform_interface: ^6.0.0
fake_cloud_firestore: ^4.0.0
firebase_auth_mocks: ^0.15.0


# For information on the generic Dart part of this file, see the
Expand Down
107 changes: 107 additions & 0 deletions test/widget_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_auth_mocks/firebase_auth_mocks.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:firebase_core_platform_interface/test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:postbox_game/main.dart';
import 'package:postbox_game/theme.dart';
import 'package:postbox_game/user_repository.dart';

// ---------------------------------------------------------------------------
// Firebase mock setup
// ---------------------------------------------------------------------------

/// Call once per test run (or in setUp) to initialise the Firebase platform
/// mock so that Firebase.initializeApp() succeeds without hitting real servers.
Future<void> setupFirebaseMocks() async {
TestWidgetsFlutterBinding.ensureInitialized();
setupFirebaseCoreMocks();
await Firebase.initializeApp();
}

// ---------------------------------------------------------------------------
// Widget-level smoke tests
// ---------------------------------------------------------------------------

void main() {
setUpAll(setupFirebaseMocks);

group('App smoke tests', () {
testWidgets('PostboxGame widget tree renders without crashing', (tester) async {
await tester.pumpWidget(PostboxGame());
await tester.pump(); // process one frame
// Should show SplashScreen or LoginScreen (Firebase is mocked)
expect(find.byType(MaterialApp), findsOneWidget);
});
});

// ---------------------------------------------------------------------------
// AppSpacing unit tests (from phase4-polish)
// ---------------------------------------------------------------------------

group('AppSpacing', () {
test('spacing scale is strictly increasing', () {
expect(AppSpacing.xs, lessThan(AppSpacing.sm));
Expand All @@ -15,4 +56,70 @@ void main() {
expect(AppSpacing.xs, greaterThan(0));
});
});

// ---------------------------------------------------------------------------
// UserRepository unit tests
// ---------------------------------------------------------------------------

group('UserRepository', () {
late FakeFirebaseFirestore fakeFirestore;
late MockFirebaseAuth mockAuth;
late UserRepository repo;

setUp(() {
fakeFirestore = FakeFirebaseFirestore();
mockAuth = MockFirebaseAuth();
repo = UserRepository(
firebaseAuth: mockAuth,
firestore: fakeFirestore,
);
});

test('signUp writes displayName to Firestore', () async {
// MockFirebaseAuth creates a user automatically on signUp.
await repo.signUp(email: 'test@example.com', password: 'password123');

final uid = mockAuth.currentUser?.uid;
expect(uid, isNotNull);

final doc = await fakeFirestore.collection('users').doc(uid).get();
expect(doc.data()?['displayName'], equals('test'));
});

test('getDisplayName returns stored name', () async {
const uid = 'user-abc';
await fakeFirestore.collection('users').doc(uid).set({'displayName': 'Postbox Pete'});

final name = await repo.getDisplayName(uid);
expect(name, equals('Postbox Pete'));
});

test('getDisplayName returns null for unknown uid', () async {
final name = await repo.getDisplayName('nonexistent-uid');
expect(name, isNull);
});

test('isSignedIn returns false when no user', () async {
final signedIn = await repo.isSignedIn();
expect(signedIn, isFalse);
});

test('isSignedIn returns true when a user is signed in', () async {
final auth = MockFirebaseAuth(signedIn: true);
final repo = UserRepository(firebaseAuth: auth, firestore: fakeFirestore);
expect(await repo.isSignedIn(), isTrue);
});

test('signUp writes email to Firestore', () async {
await repo.signUp(email: 'alice@example.com', password: 'password');
final uid = mockAuth.currentUser?.uid;
expect(uid, isNotNull);
final doc = await fakeFirestore
.collection('users')
.doc(uid)
.get();
expect(doc.data()?['email'], equals('alice@example.com'));
});
});

}
Loading