공개페이지
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import 'package:lanebow/services/public_event_service.dart';
|
||||
import 'package:lanebow/utils/web_storage.dart';
|
||||
|
||||
class FakeHttp implements PublicHttpClient {
|
||||
Response<dynamic>? lastResponse;
|
||||
Map<String, dynamic>? lastHeaders;
|
||||
String? lastPath;
|
||||
dynamic lastData;
|
||||
|
||||
int statusCode = 200;
|
||||
Map<String, dynamic> responseData = const {'ok': true};
|
||||
|
||||
@override
|
||||
Future<Response<dynamic>> get(String path, {Map<String, dynamic>? headers}) async {
|
||||
lastPath = path;
|
||||
lastData = null;
|
||||
lastHeaders = headers;
|
||||
if (statusCode >= 400) {
|
||||
throw DioException(
|
||||
requestOptions: RequestOptions(path: path),
|
||||
response: Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData),
|
||||
type: DioExceptionType.badResponse,
|
||||
);
|
||||
}
|
||||
lastResponse = Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData);
|
||||
return lastResponse!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response<dynamic>> post(String path, {data, Map<String, dynamic>? headers}) async {
|
||||
lastPath = path;
|
||||
lastData = data;
|
||||
lastHeaders = headers;
|
||||
if (statusCode >= 400) {
|
||||
throw DioException(
|
||||
requestOptions: RequestOptions(path: path),
|
||||
response: Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData),
|
||||
type: DioExceptionType.badResponse,
|
||||
);
|
||||
}
|
||||
lastResponse = Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData);
|
||||
return lastResponse!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response<dynamic>> put(String path, {data, Map<String, dynamic>? headers}) async {
|
||||
lastPath = path;
|
||||
lastData = data;
|
||||
lastHeaders = headers;
|
||||
if (statusCode >= 400) {
|
||||
throw DioException(
|
||||
requestOptions: RequestOptions(path: path),
|
||||
response: Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData),
|
||||
type: DioExceptionType.badResponse,
|
||||
);
|
||||
}
|
||||
lastResponse = Response(requestOptions: RequestOptions(path: path), statusCode: statusCode, data: responseData);
|
||||
return lastResponse!;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
group('PublicEventService.enter', () {
|
||||
test('saves token when response includes token', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 200
|
||||
..responseData = {'token': 'TKN', 'event': {'id': 1}};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'abc123';
|
||||
|
||||
// ensure empty
|
||||
WebStorage.removeItem(PublicEventService.tokenKey(hash));
|
||||
|
||||
final data = await svc.enter(hash, password: 'pw');
|
||||
expect(data['token'], 'TKN');
|
||||
expect(WebStorage.getItem(PublicEventService.tokenKey(hash)), 'TKN');
|
||||
expect(fake.lastPath, '/api/public/' + hash);
|
||||
});
|
||||
|
||||
test('removes saved token on 401/403', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 401
|
||||
..responseData = {'message': 'unauthorized'};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'abc401';
|
||||
|
||||
// preset token
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'OLD');
|
||||
|
||||
await expectLater(
|
||||
svc.enter(hash, password: 'wrong'),
|
||||
throwsA(isA<DioException>()),
|
||||
);
|
||||
expect(WebStorage.getItem(PublicEventService.tokenKey(hash)), isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('PublicEventService.updateScore', () {
|
||||
test('sends Authorization header when token saved', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 200
|
||||
..responseData = {'ok': true};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'hhh';
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'TKN2');
|
||||
|
||||
await svc.updateScore(
|
||||
hash,
|
||||
participantId: '10',
|
||||
gameNumber: 1,
|
||||
score: 200,
|
||||
handicap: 0,
|
||||
);
|
||||
|
||||
expect(fake.lastPath, '/api/public/' + hash + '/score');
|
||||
expect(fake.lastHeaders?['Authorization'], 'Bearer TKN2');
|
||||
expect(fake.lastData['participantId'], '10');
|
||||
expect(fake.lastData['gameNumber'], 1);
|
||||
expect(fake.lastData['score'], 200);
|
||||
});
|
||||
});
|
||||
|
||||
group('PublicEventService.fetchEvent', () {
|
||||
test('uses GET and Authorization header when token saved', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 200
|
||||
..responseData = {'event': {'id': 'E1'}};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'fetch1';
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'TKF');
|
||||
|
||||
final data = await svc.fetchEvent(hash);
|
||||
expect(data['event']['id'], 'E1');
|
||||
expect(fake.lastPath, '/api/public/' + hash);
|
||||
expect(fake.lastHeaders?['Authorization'], 'Bearer TKF');
|
||||
});
|
||||
});
|
||||
|
||||
group('PublicEventService.enter edge cases', () {
|
||||
test('404 does not remove saved token', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 404
|
||||
..responseData = {'message': 'not found'};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'nf404';
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'KEEP');
|
||||
await expectLater(svc.enter(hash), throwsA(isA<DioException>()));
|
||||
expect(WebStorage.getItem(PublicEventService.tokenKey(hash)), 'KEEP');
|
||||
});
|
||||
});
|
||||
|
||||
group('PublicEventService.addGuest', () {
|
||||
test('sends payload and header', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 200
|
||||
..responseData = {'ok': true};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'guest';
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'TG');
|
||||
|
||||
await svc.addGuest(hash, name: '홍길동', phone: '010', gender: 'M', average: 190);
|
||||
expect(fake.lastPath, '/api/public/' + hash + '/guest');
|
||||
expect(fake.lastHeaders?['Authorization'], 'Bearer TG');
|
||||
expect(fake.lastData['name'], '홍길동');
|
||||
expect(fake.lastData['phone'], '010');
|
||||
expect(fake.lastData['gender'], 'M');
|
||||
expect(fake.lastData['average'], 190);
|
||||
});
|
||||
});
|
||||
|
||||
group('PublicEventService.updateScore errors', () {
|
||||
test('propagates server error 500', () async {
|
||||
final fake = FakeHttp()
|
||||
..statusCode = 500
|
||||
..responseData = {'message': 'oops'};
|
||||
final svc = PublicEventService.forTest(fake);
|
||||
final hash = 'err';
|
||||
WebStorage.setItem(PublicEventService.tokenKey(hash), 'TE');
|
||||
|
||||
await expectLater(
|
||||
svc.updateScore(hash, participantId: 'p1', gameNumber: 1, score: 100),
|
||||
throwsA(isA<DioException>()),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user