LCOV - code coverage report

Current view: | top level - lib/utils - url_utils.dart |  |  | Coverage | Total | Hit
Test: | lcov.info |  | Lines: | 9.4 % | 32 | 3
Test Date: | 2025-08-12 03:21:51 |  | Functions: | - | 0 | 0

                Line data    Source code

           1              : import 'dart:math';
           2              :
           3              : import 'package:flutter/material.dart';
           4              : import 'package:flutter/scheduler.dart';
           5              : import 'package:flutter/services.dart';
           6              :
           7              : import 'test_utils.dart';
           8              :
           9              : /// URL 관련 유틸리티 기능을 제공하는 클래스
          10              : class UrlUtils {
          11              :   /// 이벤트 공개 URL의 기본 도메인
          12              :   static const String eventBaseUrl = 'https://bowling.example.com/events/';
          13              :
          14              :   /// 공개 URL 해시 생성
          15              :   ///
          16              :   /// 8자리 영숫자 해시를 생성합니다.
          17              :   /// 보안 및 충돌 방지를 위해 충분한 길이와 랜덤성을 가집니다.
          18              :   /// 테스트 환경에서는 예측 가능한 해시를 반환합니다.
          19            1 :   static String generatePublicHash() {
          20              :     // 테스트 환경에서는 예측 가능한 해시 반환
          21            1 :     if (TestUtils.isInTest) {
          22            1 :       return TestUtils.getTestHash();
          23              :     }
          24              :
          25              :     // 일반 환경에서는 랜덤 해시 생성
          26              :     const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
          27            0 :     final random = Random();
          28            0 :     return String.fromCharCodes(
          29            0 :       Iterable.generate(
          30              :         8,
          31            0 :         (_) => chars.codeUnitAt(random.nextInt(chars.length)),
          32              :       ),
          33              :     );
          34              :   }
          35              :
          36              :   /// 이벤트 공개 URL 생성
          37              :   ///
          38              :   /// [hash] 값을 기반으로 완전한 이벤트 공개 URL을 생성합니다.
          39            0 :   static String getEventPublicUrl(String hash) {
          40            0 :     return '$eventBaseUrl$hash';
          41              :   }
          42              :
          43              :   /// URL을 클립보드에 복사하고 스낵바로 알림
          44              :   ///
          45              :   /// [context]는 스낵바를 표시할 BuildContext입니다.
          46              :   /// [url]은 복사할 URL 문자열입니다.
          47              :   /// [duration]은 스낵바 표시 시간입니다. 기본값은 2초입니다.
          48            0 :   static void copyUrlToClipboard(BuildContext context, String url, {Duration? duration}) {
          49            0 :     Clipboard.setData(ClipboardData(text: url));
          50              :
          51              :     // 테스트 환경에서 안전하게 스낵바 표시
          52            0 :     if (TestUtils.isInTest) {
          53              :       // 테스트 환경에서는 로그만 출력
          54            0 :       debugPrint('클립보드에 URL 복사됨: $url');
          55              :       return;
          56              :     }
          57              :
          58              :     // 일반 환경에서는 스낵바 표시
          59            0 :     SchedulerBinding.instance.addPostFrameCallback((_) {
          60            0 :       if (context.mounted) {
          61            0 :         final snackBar = SnackBar(
          62              :           content: const Text('공개 URL이 클립보드에 복사되었습니다'),
          63            0 :           action: SnackBarAction(
          64              :             label: '확인',
          65            0 :             onPressed: () {},
          66              :           ),
          67              :           duration: duration ?? const Duration(seconds: 2),
          68              :         );
          69              :
          70            0 :         ScaffoldMessenger.of(context).showSnackBar(snackBar);
          71              :       }
          72              :     });
          73              :   }
          74              :
          75              :   /// 해시 생성/재생성 후 스낵바로 알림
          76              :   ///
          77              :   /// [context]는 스낵바를 표시할 BuildContext입니다.
          78              :   /// [isNew]는 새로 생성된 해시인지 여부입니다. true면 생성, false면 재생성 메시지를 표시합니다.
          79              :   /// [hash]는 생성된 해시 값입니다.
          80              :   ///
          81              :   /// 주의: 이 메서드는 더 이상 직접 사용하지 않습니다. 테스트 환경에서 문제가 발생할 수 있습니다.
          82              :   /// 대신 각 화면에서 직접 스낵바를 표시하는 것이 좋습니다.
          83            0 :   @Deprecated('테스트 환경에서 문제가 발생할 수 있습니다. 대신 각 화면에서 직접 스낵바를 표시하세요.')
          84              :   static void showHashGenerationSnackbar(BuildContext context, bool isNew, String hash) {
          85              :     final message = isNew
          86              :         ? '공개 URL 해시가 생성되었습니다'
          87              :         : '공개 URL 해시가 재생성되었습니다. 이전 URL은 더 이상 유효하지 않습니다';
          88              :
          89            0 :     final url = getEventPublicUrl(hash);
          90              :
          91              :     // 테스트 환경에서는 항상 로그만 출력
          92            0 :     if (TestUtils.isInTest) {
          93            0 :       debugPrint('해시 생성 완료: $message, URL: $url');
          94              :       return;
          95              :     }
          96              :
          97              :     // 일반 환경에서는 스낵바 표시 (context가 유효한지 확인)
          98            0 :     if (context.mounted) {
          99            0 :       SchedulerBinding.instance.addPostFrameCallback((_) {
         100            0 :         if (context.mounted) {
         101              :           try {
         102            0 :             final snackBar = SnackBar(
         103            0 :               content: Text(message),
         104            0 :               action: SnackBarAction(
         105              :                 label: 'URL 복사',
         106            0 :                 onPressed: () => copyUrlToClipboard(context, url),
         107              :               ),
         108              :               duration: const Duration(seconds: 4),
         109              :             );
         110              :
         111            0 :             ScaffoldMessenger.of(context).showSnackBar(snackBar);
         112              :           } catch (e) {
         113            0 :             debugPrint('스낵바 표시 오류: $e');
         114              :           }
         115              :         }
         116              :       });
         117              :     }
         118              :   }
         119              : }

Generated by: LCOV version 2.3.1-1