ReadingAnnotationsTest.php 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. use App\Models\Discussion;
  3. use App\Services\PaliContentService;
  4. use Illuminate\Foundation\Testing\RefreshDatabase;
  5. use Illuminate\Support\Facades\Cache;
  6. use Illuminate\Support\Str;
  7. uses(RefreshDatabase::class);
  8. /**
  9. * 阅读页批注内嵌:type='commentary'(注释书对应,带出处)与 type='note'(普通边注,无出处)。
  10. */
  11. /** 建 channel + 一句根本译文(book 9101 第 1 段),返回 [channel uid, 句子] */
  12. function makeAnnotatedSentence(): array
  13. {
  14. $channel = makeChannel(makeStudio('anno-owner'), 'anno channel');
  15. $sentence = makeSentence($channel, 9101, 1, 1, 'first sentence');
  16. return [$channel, $sentence];
  17. }
  18. function makeAnnotation(string $resId, string $type, string $content, int $posEnd): Discussion
  19. {
  20. $discussion = new Discussion;
  21. $discussion->forceFill([
  22. 'res_id' => $resId,
  23. 'res_type' => 'sentence',
  24. 'type' => $type,
  25. 'title' => $content,
  26. 'content' => $content,
  27. 'content_type' => 'markdown',
  28. 'editor_uid' => makeStudio('anno-'.Str::random(6)),
  29. 'pos_start' => 0,
  30. 'pos_end' => $posEnd,
  31. 'quote_exact' => 'first',
  32. ])->save();
  33. return $discussion;
  34. }
  35. it('injects a commentary annotation with a cite link', function () {
  36. [$channel, $sentence] = makeAnnotatedSentence();
  37. // 义注句:commentary 的 content 是它的句子模板,渲染成它在同 channel 的译文
  38. makeSentence($channel, 9102, 7, 3, '义注这么说');
  39. makeAnnotation($sentence->uid, 'commentary', '{{9102-7-3-3}}', 5);
  40. $display = $this->getJson("/api/v3/tipitaka-reading/{$channel}?book=9101&para=1")
  41. ->assertOk()
  42. ->json('data.0.display');
  43. expect($display)
  44. ->toContain('义注这么说')
  45. ->toContain('<cite class="anno-jump" data-book="9102" data-para="7" data-start="3" data-end="3">义注</cite>');
  46. });
  47. it('injects a plain note annotation without a cite link', function () {
  48. [$channel, $sentence] = makeAnnotatedSentence();
  49. // 普通边注:content 就是注解正文本身
  50. makeAnnotation($sentence->uid, 'note', '这里的 dassana 指见到佛陀。', 5);
  51. $display = $this->getJson("/api/v3/tipitaka-reading/{$channel}?book=9101&para=1")
  52. ->assertOk()
  53. ->json('data.0.display');
  54. // 正文照原样进 sidenote,紧跟 </span> 收尾——没有 <cite> 出处
  55. expect($display)
  56. ->toContain('这里的 dassana 指见到佛陀。</span>')
  57. ->not->toContain('anno-jump');
  58. });
  59. it('injects both kinds on the same sentence, note first at the same position', function () {
  60. [$channel, $sentence] = makeAnnotatedSentence();
  61. makeSentence($channel, 9102, 7, 3, '义注这么说');
  62. makeAnnotation($sentence->uid, 'commentary', '{{9102-7-3-3}}', 5);
  63. makeAnnotation($sentence->uid, 'note', '译者按。', 5);
  64. $display = $this->getJson("/api/v3/tipitaka-reading/{$channel}?book=9101&para=1")
  65. ->assertOk()
  66. ->json('data.0.display');
  67. expect(mb_strpos($display, '译者按。'))->toBeLessThan(mb_strpos($display, '义注这么说'));
  68. });
  69. it('drops the paragraph cache when either kind of annotation changes', function () {
  70. [$channel, $sentence] = makeAnnotatedSentence();
  71. $url = "/api/v3/tipitaka-reading/{$channel}?book=9101&para=1";
  72. $this->getJson($url)->assertOk();
  73. $key = PaliContentService::paragraphCacheKey(9101, 1, $channel, 'html');
  74. expect(Cache::has($key))->toBeTrue();
  75. makeAnnotation($sentence->uid, 'note', '译者按。', 5);
  76. expect(Cache::has($key))->toBeFalse();
  77. expect($this->getJson($url)->json('data.0.display'))->toContain('译者按。');
  78. });