Skip to content

Conversation

@uzulla
Copy link
Owner

@uzulla uzulla commented Nov 20, 2025

Add UPDATE_EMBED_SNAPSHOTS environment variable to update both HTTP response cache and fixtures together when running tests.

Changes:

  • Add UPDATE_EMBED_SNAPSHOTS=1 to fetch from network and update snapshots
  • Add EMBED_STRICT_CACHE=1 to fail if cache is missing (for CI)
  • Update GitHub Actions workflow to use EMBED_STRICT_CACHE
  • Add comprehensive documentation for snapshot testing in README

Usage:
UPDATE_EMBED_SNAPSHOTS=1 ./vendor/bin/phpunit --filter testYoutube

Summary by CodeRabbit

リリースノート

  • Documentation(ドキュメント)

    • README に「Testing」セクションを追加。テスト実行方法、キャッシュ/フィクスチャのモードと優先順、キャッシュ更新手順を明記。
  • Tests(テスト)

    • テスト実行でのキャッシュ/フィクスチャ挙動を環境変数で制御可能に。厳密モードでは欠損フィクスチャで失敗、更新モードではフィクスチャを保存してスキップする振る舞いを導入。
  • Chores

    • CI 実行時にキャッシュ厳密化を有効にする環境変数を追加。

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Walkthrough

CIワークフローに EMBED_STRICT_CACHE を追加し、テスト基盤(PagesTestCase)に環境変数駆動のキャッシュ/フィクスチャモードとそれに応じた assertEmbed の分岐処理を実装、README にテストとキャッシュ更新手順を追記しました。

Changes

Cohort / File(s) Summary
CI設定
\.github/workflows/test.yml``
Tests ステップに EMBED_STRICT_CACHE=1 環境変数を追加
ドキュメント
\README.md``
「Testing」セクションを追加:テスト実行コマンド、スナップショットモード(環境変数)、キャッシュ構造、キャッシュ更新手順、CIでのキャッシュ要件を説明
テスト基盤
\tests/PagesTestCase.php``
環境変数ベースのモード管理を追加:getCacheMode()getFixturesMode()isStrictMode() を導入。assertEmbed を拡張して厳密モード検証、フィクスチャ保存・更新、欠落フィクスチャ時のスキップ/失敗処理を実装

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI workflow
  participant TR as Test Runner
  participant PTC as PagesTestCase
  participant FS as Fixtures/Cache

  note over CI: CI sets EMBED_STRICT_CACHE=1
  CI->>TR: start tests
  TR->>PTC: run assertEmbed(test)
  PTC->>PTC: getCacheMode(), getFixturesMode(), isStrictMode()
  alt strict mode (EMBED_STRICT_CACHE=1)
    PTC->>FS: check fixture exists
    FS-->>PTC: missing
    PTC-->>TR: fail test (strict)
  else update fixtures mode
    PTC->>FS: write fixture
    FS-->>PTC: saved
    PTC-->>TR: skip test (fixture updated)
  else default/non-strict
    PTC->>FS: check fixture
    alt fixture exists
      FS-->>PTC: returns fixture
      PTC-->>TR: assert using fixture
    else missing
      PTC->>FS: write fixture
      FS-->>PTC: saved
      PTC-->>TR: skip test (new fixture)
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20分

  • 注目箇所:
    • tests/PagesTestCase.php: 新メソッドと assertEmbed の分岐ロジック(厳密モード・更新・スキップ・保存)の正しさと副作用(テストスキップ/失敗の扱い)を重点確認
    • README.md: 環境変数の説明と手順が実際の挙動と一致しているか確認
    • .github/workflows/test.yml: CI 環境変数の意図と他のジョブ影響を軽く確認

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding environment variable support for test snapshot modes, which is the core focus of the PR across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/snapshot-environment-variables

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/PagesTestCase.php (1)

125-142: UPDATE_EMBED_SNAPSHOTSEMBED_STRICT_CACHE の併用時に、README の仕様通りに動作していません

検証結果:

  • readData() は存在しないフィクスチャに対して null を返すことを確認しました(line 163)
  • README の「UPDATE_EMBED_SNAPSHOTS が優先」という仕様を確認しました(line 376)
  • 現在のコード: strict チェック(line 126-127)が UPDATE チェック(line 131)より先に実行されるため、両フラグ設定時にフィクスチャが無いとテストが失敗し、UPDATE モードに進みません

これは仕様違反です。提案された修正(UPDATE モード判定を先に実行する順序変更と === null の明示化)を適用してください:

-        // In strict mode, fail if fixture is missing
-        if (!$expected && self::isStrictMode()) {
-            $this->fail("Fixture not found for {$url}");
-        }
-
-        // Update mode: save fixture and skip
-        if (self::getFixturesMode() === 1) {
+        // Update mode: always save fixture and skip assertions
+        if (self::getFixturesMode() === 1) {
             self::writeData($uri, $data);
             echo PHP_EOL."Save fixture: {$url}";
             $this->markTestSkipped('Skipped assertion for '.$url);
-        } elseif (!$expected) {
-            // Missing fixture in non-strict mode: create and skip
+
+            return;
+        }
+
+        // In strict mode, fail if fixture is missing
+        if ($expected === null && self::isStrictMode()) {
+            $this->fail("Fixture not found for {$url}");
+        }
+
+        if ($expected === null) {
+            // Missing fixture in non-strict mode: create and skip
             self::writeData($uri, $data);
             echo PHP_EOL."Save fixture: {$url}";
             $this->markTestSkipped('Skipped assertion for '.$url);
+
+            return;
+        }
+
+        $this->assertEquals($expected, $data, $url);
-        } else {
-            $this->assertEquals($expected, $data, $url);
-        }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between a0bdfef and c88c244.

📒 Files selected for processing (3)
  • .github/workflows/test.yml (1 hunks)
  • README.md (1 hunks)
  • tests/PagesTestCase.php (3 hunks)
🔇 Additional comments (5)
.github/workflows/test.yml (1)

43-46: CI のテストステップへの EMBED_STRICT_CACHE=1 設定は実装/ドキュメントと整合しています

composer test 実行時にのみ EMBED_STRICT_CACHE=1 を付与しており、PagesTestCase::getCacheMode() と README の「For CI environments」の説明どおり、CI ではキャッシュ欠如を検知して落とす構成になっていて問題なさそうです。

tests/PagesTestCase.php (4)

18-40: CACHE / FIXTURES 定数のモード定義と env 上書きの説明が明確で良いです

キャッシュモード(-1〜2)とフィクスチャモード(0/1)の意味、および UPDATE_EMBED_SNAPSHOTSEMBED_STRICT_CACHE による上書きルールがコメントで整理されており、テスト戦略の意図が読み取りやすくなっています。実装とも整合しているので、このままで問題ないと思います。


65-82: getCacheMode() による env 起点のキャッシュモード切り替えは意図どおりです

UPDATE_EMBED_SNAPSHOTS 優先で 2(キャッシュ上書き)、それ以外で EMBED_STRICT_CACHE による -1(キャッシュ必須)、いずれも未設定時は static::CACHE という分岐になっており、README の説明および CI 設定(EMBED_STRICT_CACHE=1)と噛み合っています。特に懸念点はありません。


83-95: getFixturesMode() の実装もシンプルで UPDATE_EMBED_SNAPSHOTS の用途に合っています

UPDATE_EMBED_SNAPSHOTS がセットされていればフィクスチャ更新モード(1)、それ以外は static::FIXTURES にフォールバックするだけの構造で、Snapshot 更新フローの意図を過不足なく表現できていると思います。


96-102: strict モードフラグと getEmbed() でのキャッシュモード適用は妥当です

isStrictMode()EMBED_STRICT_CACHE の有無のみを見て bool を返し、getEmbed() 側では FileClient に対して self::getCacheMode() を渡す構造になっており、キャッシュ戦略の切り替え点が一箇所に集約されていて分かりやすいです。FileClient との責務分担も明確で、ここについてはそのままで良さそうです。

Also applies to: 110-112

Comment on lines +355 to +421
## Testing

### Running tests

```bash
composer test
# or
./vendor/bin/phpunit
```

### Snapshot modes

The test suite uses cached HTTP responses and fixtures to avoid network requests during testing. You can control this behavior using environment variables:

| Environment Variable | Description |
|---------------------|-------------|
| `UPDATE_EMBED_SNAPSHOTS=1` | Fetch from network and update both cache and fixtures |
| `EMBED_STRICT_CACHE=1` | Fail if cache or fixture doesn't exist (useful for CI) |

By default (no environment variables set), tests read from cache and generate missing files automatically.

**Note:** If both `UPDATE_EMBED_SNAPSHOTS` and `EMBED_STRICT_CACHE` are set, `UPDATE_EMBED_SNAPSHOTS` takes precedence.

### Cache structure

The test framework uses two types of cached data:

- **Response cache** (`tests/cache/`): Cached HTTP responses from external sites
- **Fixtures** (`tests/fixtures/`): Expected test results (metadata extracted from cached responses)

### How to update cache

#### When a website changes its HTML structure

If a website updates its HTML and you need to update the cached response and fixture:

```bash
# Update cache and fixture for a specific test
UPDATE_EMBED_SNAPSHOTS=1 ./vendor/bin/phpunit --filter testYoutube
```

#### When adding a new test

After adding a new URL to test:

```bash
# This will fetch the response and create both cache and fixture
UPDATE_EMBED_SNAPSHOTS=1 ./vendor/bin/phpunit --filter testNewSite
```

#### Update all caches at once

To refresh all cached responses and fixtures from the network:

```bash
UPDATE_EMBED_SNAPSHOTS=1 ./vendor/bin/phpunit
```

#### For CI environments

Ensure all tests run strictly from cache (fail if any cache is missing):

```bash
EMBED_STRICT_CACHE=1 ./vendor/bin/phpunit
```

---
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Testing セクションは分かりやすいですが、env 併用時の挙動説明が実装と一部ずれています

Snapshot modesNote で「UPDATE_EMBED_SNAPSHOTSEMBED_STRICT_CACHE の両方がセットされた場合は UPDATE_EMBED_SNAPSHOTS が優先」とありますが、現状の tests/PagesTestCase::assertEmbed() では両方がセットされ、かつフィクスチャが存在しない場合に「strict チェックの fail」が先に走り、フィクスチャ更新には到達しません。

README どおりの挙動にするなら、コード側で UPDATE_EMBED_SNAPSHOTS を完全に優先するよう(たとえば getFixturesMode() の判定を先に実行し、strict チェックより前にフィクスチャを書き出して skip するなど)調整するか、逆に現在の実装を正とするなら Note の文言を修正しておくと読者が混乱しにくいと思います。この点は tests/PagesTestCase.php 側への修正案コメントも併せてご確認ください。


🏁 Script executed:

#!/bin/bash
# Locate and examine PagesTestCase.php, focusing on assertEmbed() method
fd -e php -p "*PagesTestCase*" | head -5

Length of output: 294


🏁 Script executed:

#!/bin/bash
# Search for the assertEmbed method and surrounding context with both env var checks
rg -n -A 30 "function assertEmbed" --type php

Length of output: 1985


🏁 Script executed:

#!/bin/bash
# Also check for EMBED_STRICT_CACHE and UPDATE_EMBED_SNAPSHOTS references in tests
rg -n "EMBED_STRICT_CACHE|UPDATE_EMBED_SNAPSHOTS" --type php -B 2 -A 2

Length of output: 2000


README.md の Testing セクション記述と tests/PagesTestCase.php の実装が不一致である点が確認されました

検証結果、以下が明らかになりました:

tests/PagesTestCase.phpassertEmbed() メソッドでは:

  • 126~128行目if (!$expected && self::isStrictMode())先に実行され、フィクスチャが存在しない場合にここで失敗
  • 131~134行目if (self::getFixturesMode() === 1) でフィクスチャ更新が実行されるはずだが、上記の厳密モードチェックに引っかかると到達しない

つまり、UPDATE_EMBED_SNAPSHOTS=1EMBED_STRICT_CACHE=1 の両方がセットされ、フィクスチャが欠落している場合、README で謳う「UPDATE_EMBED_SNAPSHOTS が優先」という動作は実現されていません。

対応方法

  1. コード側修正getFixturesMode() の判定を先に実行し、UPDATE_EMBED_SNAPSHOTS が有効な場合はフィクスチャを作成してから厳密モードチェックをスキップ
  2. README 修正:現在の実装に合わせ、Note 文言を「厳密モードが優先される」に修正

いずれかの対応を行い、README とコード実装を一致させてください。

🤖 Prompt for AI Agents
README.md around lines 355-421: the README claims UPDATE_EMBED_SNAPSHOTS takes
precedence over EMBED_STRICT_CACHE but tests/PagesTestCase.php currently checks
strict-mode before fixtures-mode (see lines ~126-134), causing the opposite
behavior; update tests/PagesTestCase.php so getFixturesMode() is evaluated
before the strict-mode check—if fixtures mode indicates update
(UPDATE_EMBED_SNAPSHOTS=1) create/update the fixture first and only then skip or
re-evaluate the strict-mode failure path, ensuring that when both env vars are
set the snapshot-update path runs; alternatively, if you prefer keeping current
code, change the README note to state that strict mode takes precedence.

Add UPDATE_EMBED_SNAPSHOTS environment variable to update both
HTTP response cache and fixtures together when running tests.

Changes:
- Add UPDATE_EMBED_SNAPSHOTS=1 to fetch from network and update snapshots
- Add EMBED_STRICT_CACHE=1 to fail if cache is missing (for CI)
- Update GitHub Actions workflow to use EMBED_STRICT_CACHE
- Add comprehensive documentation for snapshot testing in README

Usage:
  UPDATE_EMBED_SNAPSHOTS=1 ./vendor/bin/phpunit --filter testYoutube
@uzulla uzulla force-pushed the feature/snapshot-environment-variables branch from c88c244 to ef4df71 Compare November 22, 2025 15:42
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/PagesTestCase.php (1)

125-142: 条件チェックの順序に問題があります

Strictモードのチェック(125-128行目)が更新モードのチェック(131-135行目)より前にあるため、UPDATE_EMBED_SNAPSHOTS=1EMBED_STRICT_CACHE=1の両方が設定されている場合、フィクスチャが存在しないとテストが失敗してしまいます。更新モードでは新しいフィクスチャを作成することが目的なので、この動作は意図に反します。

更新モードを最初にチェックするよう順序を変更してください:

         $uri = $extractor->getRequest()->getUri();
         $data = self::getData($extractor);
         $expected = self::readData($uri);
 
-        // In strict mode, fail if fixture is missing
-        if (!$expected && self::isStrictMode()) {
-            $this->fail("Fixture not found for {$url}");
-        }
-
         // Update mode: save fixture and skip
         if (self::getFixturesMode() === 1) {
             self::writeData($uri, $data);
             echo PHP_EOL."Save fixture: {$url}";
             $this->markTestSkipped('Skipped assertion for '.$url);
+        } elseif (!$expected && self::isStrictMode()) {
+            // In strict mode, fail if fixture is missing
+            $this->fail("Fixture not found for {$url}");
         } elseif (!$expected) {
             // Missing fixture in non-strict mode: create and skip
             self::writeData($uri, $data);

これにより、更新モードが優先され、strictモードの矛盾した設定でも正しく動作します。

♻️ Duplicate comments (1)
README.md (1)

376-376: 環境変数の優先順位の説明が実装と矛盾している(既知の問題)。

このノートの説明「UPDATE_EMBED_SNAPSHOTSEMBED_STRICT_CACHE より優先される」と、tests/PagesTestCase.php の実装が一致していません。過去のレビューで指摘されたとおり、実装では strict モードチェック(isStrictMode() の判定)がフィクスチャ更新処理より先に実行されるため、両方の環境変数が設定された場合、実際には strict モードが優先されます。

以下のいずれかの対応を行ってください:

  1. 実装を修正する場合tests/PagesTestCase.phpassertEmbed() メソッドで getFixturesMode() の判定を先に実行し、UPDATE_EMBED_SNAPSHOTS が有効な場合はフィクスチャを更新してから strict モードチェックをスキップする
  2. README を修正する場合:このノートを「strict モードが優先される」に変更する

過去のレビュー指摘(lines 355-421)を参照してください。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between c88c244 and ef4df71.

📒 Files selected for processing (3)
  • .github/workflows/test.yml (1 hunks)
  • README.md (1 hunks)
  • tests/PagesTestCase.php (3 hunks)
🔇 Additional comments (4)
README.md (1)

357-375: Testing セクションの構成と説明品質は良好です。

Running tests、Cache structure、How to update cache のセクションは論理的に構成されており、実用的で明確な例が提供されています。特に環境変数の表形式での説明と、具体的なテスト更新シナリオ(特定テスト、新規テスト、全体更新、CI環境)をカバーしている点は好評です。

上述の優先順位に関する矛盾が解決されれば、このドキュメントは有用なリソースになります。

Also applies to: 378-419

.github/workflows/test.yml (1)

45-46: LGTM!

CI環境でキャッシュとフィクスチャの存在を確認する適切な設定です。これによりテストの再現性が向上します。

tests/PagesTestCase.php (2)

18-39: ドキュメントが明確で分かりやすい

各モードの動作と環境変数による上書きが適切に説明されています。


111-111: 動的な動作を有効にする適切な変更です

定数から環境変数対応のメソッドへの変更により、実行時の柔軟な制御が可能になります。

Comment on lines +68 to +94
protected static function getCacheMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Fetch from network and override cache
if (getenv('UPDATE_EMBED_SNAPSHOTS')) {
return 2;
}

// EMBED_STRICT_CACHE=1 : Fail if cache doesn't exist
if (getenv('EMBED_STRICT_CACHE')) {
return -1;
}

return static::CACHE;
}

/**
* Get fixtures mode from environment variable or class constant
*/
protected static function getFixturesMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Override fixtures with new results
if (getenv('UPDATE_EMBED_SNAPSHOTS')) {
return 1;
}

return static::FIXTURES;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

環境変数のチェックが曖昧です

getenv()falseまたは文字列を返すため、if (getenv('UPDATE_EMBED_SNAPSHOTS'))は空でない文字列すべてに対してtrueとなります。つまりUPDATE_EMBED_SNAPSHOTS=0でも更新モードが有効になってしまいます。

以下のように明示的に値をチェックすることをお勧めします:

-        if (getenv('UPDATE_EMBED_SNAPSHOTS')) {
+        if (getenv('UPDATE_EMBED_SNAPSHOTS') === '1') {
             return 2;
         }

同様に他の環境変数チェックにも適用してください。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
protected static function getCacheMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Fetch from network and override cache
if (getenv('UPDATE_EMBED_SNAPSHOTS')) {
return 2;
}
// EMBED_STRICT_CACHE=1 : Fail if cache doesn't exist
if (getenv('EMBED_STRICT_CACHE')) {
return -1;
}
return static::CACHE;
}
/**
* Get fixtures mode from environment variable or class constant
*/
protected static function getFixturesMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Override fixtures with new results
if (getenv('UPDATE_EMBED_SNAPSHOTS')) {
return 1;
}
return static::FIXTURES;
}
protected static function getCacheMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Fetch from network and override cache
if (getenv('UPDATE_EMBED_SNAPSHOTS') === '1') {
return 2;
}
// EMBED_STRICT_CACHE=1 : Fail if cache doesn't exist
if (getenv('EMBED_STRICT_CACHE') === '1') {
return -1;
}
return static::CACHE;
}
/**
* Get fixtures mode from environment variable or class constant
*/
protected static function getFixturesMode(): int
{
// UPDATE_EMBED_SNAPSHOTS=1 : Override fixtures with new results
if (getenv('UPDATE_EMBED_SNAPSHOTS') === '1') {
return 1;
}
return static::FIXTURES;
}
🤖 Prompt for AI Agents
In tests/PagesTestCase.php around lines 68–94, the getenv() checks are too loose
(getenv returns strings) so values like "0" still evaluate true; change these
checks to explicitly compare the environment variable to the expected truthy
string(s) (e.g. strict compare to "1" or normalized lowercase in a set like
["1","true","yes"]) for UPDATE_EMBED_SNAPSHOTS and EMBED_STRICT_CACHE, and apply
the same explicit comparison for the fixtures check, ensuring the logic returns
the correct mode only when the env var is intentionally enabled.

Comment on lines +99 to +102
protected static function isStrictMode(): bool
{
return (bool) getenv('EMBED_STRICT_CACHE');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

isStrictMode()の冗長性を検討してください

isStrictMode()EMBED_STRICT_CACHEをチェックしていますが、getCacheMode()も同じ環境変数をチェックして-1を返します。代わりにself::getCacheMode() === -1を使用することで一貫性が保たれます。

リファクタリング案:

-    protected static function isStrictMode(): bool
-    {
-        return (bool) getenv('EMBED_STRICT_CACHE');
-    }
+    protected static function isStrictMode(): bool
+    {
+        return self::getCacheMode() === -1;
+    }

ただし、可読性のために現在の実装を維持する選択肢もあります。

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In tests/PagesTestCase.php around lines 99 to 102, isStrictMode() redundantly
reads getenv('EMBED_STRICT_CACHE') while getCacheMode() already interprets the
same environment variable and returns -1 for strict mode; replace the current
implementation to return self::getCacheMode() === -1 to centralize the logic and
ensure consistency (or keep the existing implementation if you prefer explicit
readability), making sure any callers rely on the canonical getCacheMode()
behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants