2
0

HeartbeatV3Test.php 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <?php
  2. /**
  3. * GET /api/v3/heartbeat —— 心跳(liveness),不是健康检查。
  4. * 真正的健康检查是 /v2/health-check,逐项探测外部依赖,将来单独迁移。
  5. *
  6. * 不用 RefreshDatabase:这个端点不碰数据库,也不需要任何夹具。
  7. *
  8. * 注意:这里断言的是响应形状,不是契约。项目尚未安装 hotmeteor/spectator,
  9. * 所以无法对着生成的 OpenAPI 规格做校验——规格与实现漂移不会被自动拦截。
  10. * 装上之后应把这些断言换成 assertValidResponse()。
  11. */
  12. afterEach(function () {
  13. @unlink(base_path('.stop'));
  14. });
  15. it('reports that the process is serving', function () {
  16. $response = $this->getJson('/api/v3/heartbeat')->assertOk();
  17. expect($response->json('data.status'))->toBe('ok');
  18. // checked_at 必须是可解析的 ISO 8601 UTC 时间
  19. expect(strtotime($response->json('data.checked_at')))->toBeGreaterThan(0);
  20. expect($response->json('data.checked_at'))->toEndWith('Z');
  21. });
  22. it('needs no authentication', function () {
  23. // 不带任何 Authorization 头也应当通过
  24. $this->getJson('/api/v3/heartbeat')->assertOk();
  25. });
  26. it('returns 503 with problem details while the stop switch is on', function () {
  27. touch(base_path('.stop'));
  28. $this->getJson('/api/v3/heartbeat')
  29. ->assertStatus(503)
  30. ->assertJson([
  31. 'title' => 'Service unavailable.',
  32. 'status' => 503,
  33. ])
  34. ->assertJsonStructure(['type', 'title', 'status', 'detail']);
  35. });
  36. it('localizes the problem detail instead of hardcoding it', function () {
  37. touch(base_path('.stop'));
  38. $detail = $this->getJson('/api/v3/heartbeat')->assertStatus(503)->json('detail');
  39. // 翻译文件缺失时 __() 会原样吐出键名,这条断言守住这种退化
  40. expect($detail)->not->toBe('site.maintenance');
  41. expect($detail)->toBe(__('site.maintenance'));
  42. // 中文翻译必须存在
  43. expect(trans('site.maintenance', [], 'zh-Hans'))->toBe('服务已进入停机维护状态');
  44. });
  45. it('recovers once the stop switch is removed', function () {
  46. touch(base_path('.stop'));
  47. $this->getJson('/api/v3/heartbeat')->assertStatus(503);
  48. unlink(base_path('.stop'));
  49. $this->getJson('/api/v3/heartbeat')->assertOk();
  50. });
  51. it('does not touch the frozen v2 heartbeat endpoint', function () {
  52. // v2 迁移期内必须原样可用:裸返回 createdAt,不带 data 包装
  53. $response = $this->getJson('/api/v2/heartbeat')->assertOk();
  54. expect($response->json('createdAt'))->not->toBeNull();
  55. expect($response->json('data'))->toBeNull();
  56. });