Files
Gnuboard7/tests/scenarios/extension-bundle-loading.yaml
T
HeuJung 0833bd1f6a fix(core,engine): 확장 번들 503 판정을 선언 축에서 소실 축으로 교체
빈 번들 503 을 "에셋을 선언한 활성 확장이 있는데 결과가 비었다" 로 판정해,
스타일 규칙이 아직 없는 0바이트 CSS 만 선언된 기본 구성이 통째로 503 이 됐다.
file_get_contents 는 0바이트에서 false 가 아니라 '' 를 돌려주므로 읽기 실패
분기도 타지 않는다. 선언 축 게터는 전부 file_exists 게이트라 부재를 셀 수 없어,
존재 게이트가 없는 getDeclaredAssetAbsolutePaths 를 통로로 두고 503 의 근거를
소실 축(findMissingDeclaredAssets)으로 옮긴다. 존재하되 비었으면 빈 200 이다.

곁들여: 실패 배너 항목명을 내부 구분 키에서 사용자 어휘로(engine-v1.64.7),
봇 화면이 없는 템플릿 CSS 를 링크하지 않도록 실재 게이트, 매니페스트 자산
선언 드리프트 4건 정정.
2026-09-04 15:36:33 +09:00

84 lines
4.1 KiB
YAML

# audit:allow test-scenario-coverage[cross_product] reason: 입력 axis 의 완전 cross-product(11축)는 조합 폭발이라 대표 조합만 마킹한다. effects 축은 면제하지 않는다 — 모든 effect 가 테스트 마킹으로 도달해야 한다.
feature: 확장(모듈/플러그인) 프론트엔드 IIFE/CSS 서버측 번들 병합
description: |
활성 모듈/플러그인의 global 전략 프론트엔드 에셋을 타입별로 하나의 번들로
서버에서 병합해 서빙, 확장 수에 비례하던 HTTP 요청을 종류별 1건으로 줄인다.
각 확장 IIFE 자가등록 계약은 유지(priority 순 물리 병합 = 실행 순서).
핵심 동작:
- ExtensionBundleService 가 getOrderedGlobalAssetPaths(uasort priority) →
buildJsBundle(`\n;\n` join, sourceMappingURL 처리) → getBundleFilePath(캐시)
- PublicModule/PluginController::serveBundle{Js,Css} → fileResponse(ETag/304)
- blade bundleUrls → ModuleAssetLoader.loadBundle(module) → loadBundle(plugin)
- 확장 캐시 버전 bump 시 새 파일명 자동 무효화, ext-bundles:cleanup GC
- bundleUrls 부재 시 개별 로딩 폴백(회귀 안전)
axes:
ext_type: [module, plugin]
asset_kind: [js, css, both]
active_combo: [none, one, multiple]
strategy: [global, layout, lazy]
environment: [production, non_production]
version_state: [first_request, cache_hit, version_bumped]
source_map_state: [present, absent]
css_url_state: [no_url, absolute_url, relative_url]
file_state: [all_present, present_empty, one_missing]
priority_order: [ascending, gdpr_lowest]
bundle_urls_present: [present, absent_fallback]
exclusions:
- { strategy: layout, active_combo: none, reason: "layout/lazy 전략은 번들 대상 아님 — 개별 레이아웃 처리" }
- { active_combo: none, version_state: cache_hit, reason: "활성 에셋 0건이면 캐시 파일을 만들지 않음 (빈 경로)" }
effects:
- ordered_by_priority_ascending_only_no_name_hardcode
- non_global_strategy_excluded_from_bundle
- js_iife_joined_with_semicolon_newline_separator
- prod_strips_source_mapping_url
- dev_rewrites_source_mapping_url_to_asset_serving_path
- per_extension_fault_tolerance_skips_missing_file_keeps_rest
- css_with_relative_url_rewritten_not_excluded
- empty_bundle_returns_empty_path_and_empty_ok_response
- prod_writes_versioned_cache_file_and_reuses_on_same_version
- non_production_rebuilds_every_request_no_disk_cache
- cleanup_removes_stale_version_bundles_only
- clear_bundles_by_type_scopes_to_prefix
- plugin_bundle_gdpr_first_when_priority_lowest
- bundle_endpoint_serves_with_etag_and_304
- bundle_url_same_origin_only
- loadbundle_single_script_single_link_append
- loadbundle_dedup_guard_no_double_load
- loadbundle_null_urls_noop
- concat_iife_self_registration_preserved
- missing_bundle_urls_falls_back_to_individual_loading
- individual_iife_requests_absent_in_browser
- gdpr_interceptor_still_active_after_merge
- extension_handlers_registered_no_console_error
- bundle_empty_with_declared_assets_returns_503
- asset_declaration_count_reads_manifest_not_built_files
- bundle_decision_is_shared_across_extension_types
- bundle_disk_write_failure_falls_back_to_memory
- bundle_script_static_miss_falls_back_to_api
- empty_result_with_present_empty_artifacts_returns_200
- empty_result_with_missing_declared_artifact_returns_503
- missing_artifact_paths_are_logged
- bundle_css_failure_banner_uses_user_vocabulary
test_files:
- tests/Unit/Services/ExtensionBundleServiceTest.php
- tests/Unit/Extension/AbstractModuleDeclaredAssetsTest.php
- tests/Unit/Extension/AbstractPluginDeclaredAssetsTest.php
- tests/Unit/Extension/BundledManifestAssetDeclarationTest.php
- tests/Feature/Api/Public/ExtensionBundleServingTest.php
- resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts
- tests/Playwright/specs/extension-bundle-loading.spec.ts
validation:
audit_rules:
- extension-bundle-url-same-origin
- extension-bundle-concat-separator
- extension-bundle-asset-path-getter
- clears-template-caches-no-file-delete