Files
maraphon-app/tests/Marathon.Infrastructure.Tests/Fixtures/marathonbet/event-football-sample.html
T
alexei.dolgolyov c4d87b59d6 fix(initial-implementation): close P2/P3/P5 review blockers — 185/185 tests green
Combined-batch reviewer flagged three real blockers + two test-infra
issues across the parallel P2/P3/P5 batch. All resolved:

PHASE 3 — DateTimeOffset UTC-kind constructor (3 sites)
  EventListingParserBase.cs:39, EventOddsParser.cs:72, ResultsParser.cs:104
  Replaced `new DateTimeOffset(DateTimeOffset.UtcNow.UtcDateTime, MoscowOffset)`
  (throws ArgumentException because UtcDateTime has Kind=Utc) with
  `DateTimeOffset.UtcNow.ToOffset(MoscowOffset)`.

PHASE 2 — EF string.Compare not translatable (3 sites)
  EventRepository.cs:34, SnapshotRepository.cs:46, ExcelExporter.cs:35
  Replaced `string.Compare(col, str, StringComparison.Ordinal)` with
  `col.CompareTo(str)` so EF Core's SQLite provider can translate the
  expression. Semantics unchanged (SQLite default collation = BINARY = ordinal).

PHASE 3 — ServerTimeProvider regex misses JSON-quoted key
  Regex `serverTime\s*:\s*"..."` only matched bare-key form. Updated to
  `"?serverTime"?\s*:\s*"..."` so the JSON-quoted form (the actual
  marathonbet.by production format) is matched.

PHASE 3 — fixture: orphan <td> elements stripped by HTML5 parser
  tests/.../Fixtures/marathonbet/event-football-sample.html — wrapped
  the <td> blocks in a proper <table><tbody><tr> hierarchy so AngleSharp
  preserves them and `td.Closest("td")` succeeds in the parser.

PHASE 2 — InMemoryDbFixture shared state across parallel tests
  All fixture instances used `Data Source=marathon_tests` causing xUnit's
  parallel-within-class runs to contaminate each other's data. Each fixture
  now uses a Guid-suffixed unique data source name.

PLAN.md — P2/P3/P5 rows updated to  Done with batch commit reference.

Test status:
  Domain.Tests:         96/96 
  Application.Tests:     1/1  
  Infrastructure.Tests: 77/77 
  UI.Tests:             11/11 
  TOTAL:               185/185 
Build: 0 warnings, 0 errors.

Deferred to later phases (per reviewer 🟡 / 🔵 notes):
- SnapshotRepository.GetAsync(Guid) uses lossy GetHashCode workaround;
  Phase 4 to fix or remove from interface.
- Excel Sport name column writes string.Empty (need lookup join in Phase 6).
- PeriodScopeMapper football n>2 falls through to "Quarter" token;
  guarded by MaxPeriods today, but defensive cleanup at Phase 9.
- Settings.razor duplicate m-rise-5 class on Localization section.
2026-05-05 12:09:44 +03:00

85 lines
3.8 KiB
HTML

<!DOCTYPE html>
<html lang="ru">
<head>
<script type="text/javascript">
//<![CDATA[
initData = {"serverTime":"2026,05,05,00,42,28","timeZoneId":"Europe/Moscow"};
//]]>
</script>
</head>
<body>
<ol class="breadcrumbs-list">
<li class="breadcrumbs-item"><a href="/su/"><span class="breadcrumb-text">Ставки на спорт</span></a></li>
<li class="breadcrumbs-item"><a href="/su/betting/Football+-+11"><span class="breadcrumb-text">Ставки на Футбол</span></a></li>
<li class="breadcrumbs-item"><a href="/su/betting/Football/Clubs.+International+-+4409575"><span class="breadcrumb-text">Клубы. Международные</span></a></li>
<li class="breadcrumbs-item"><a href="/su/betting/Football/Clubs.+International/UEFA+Champions+League+-+21255"><span class="breadcrumb-text">Лига чемпионов УЕФА</span></a></li>
<li class="breadcrumbs-item"><span class="breadcrumb-text">Арсенал - Атлетико Мадрид</span></li>
</ol>
<div class=" coupon-row" data-event-eventId="26456117" data-event-treeId="28089645"
data-event-name="Арсенал - Атлетико Мадрид" data-live="false">
<table class="coupon-row-item">
<tbody>
<tr>
<td class="hidden" data-mutable-id="eventJsonInfo"
data-json="{&quot;treeId&quot;:28089645,&quot;marathonEventId&quot;:26456117,&quot;teamNames&quot;:[&quot;Арсенал&quot;,&quot;Атлетико Мадрид&quot;],&quot;matchTime&quot;:{&quot;seconds&quot;:0,&quot;finalScore&quot;:false,&quot;isOvertime&quot;:false},&quot;eventInningTimes&quot;:[],&quot;inningScore&quot;:[],&quot;overTimeInningScore&quot;:[],&quot;currentInning&quot;:-1,&quot;serve&quot;:0,&quot;resultDescription&quot;:&quot;&quot;,&quot;matchIsComplete&quot;:false}">
</td>
</tr>
</tbody>
</table>
</div>
<table>
<tbody>
<tr>
<!-- Match Result (1x2) -->
<td data-market-type="RESULT">
<span data-selection-price="1.65" data-selection-key="26456117@Match_Result.1">1.65</span>
</td>
<td data-market-type="RESULT">
<span data-selection-price="4.1" data-selection-key="26456117@Match_Result.draw">4.10</span>
</td>
<td data-market-type="RESULT">
<span data-selection-price="5.7" data-selection-key="26456117@Match_Result.3">5.70</span>
</td>
</tr>
<tr>
<!-- Handicap -->
<td data-market-type="HANDICAP">
(-1.0)<br/>
<span data-selection-price="2.04" data-selection-key="26456117@To_Win_Match_With_Handicap.HB_H">2.04</span>
</td>
<td data-market-type="HANDICAP">
(+1.0)<br/>
<span data-selection-price="1.82" data-selection-key="26456117@To_Win_Match_With_Handicap.HB_A">1.82</span>
</td>
</tr>
<tr>
<!-- Total Goals -->
<td data-market-type="TOTAL">
(2.5)<br/>
<span data-selection-price="1.92" data-selection-key="26456117@Total_Goals.Under_2.5">1.92</span>
</td>
<td data-market-type="TOTAL">
(2.5)<br/>
<span data-selection-price="1.92" data-selection-key="26456117@Total_Goals.Over_2.5">1.92</span>
</td>
</tr>
<tr>
<!-- Period 1 (1st Half) Result -->
<td><span data-selection-price="1.80" data-selection-key="26456117@Result_-_1st_Half.RN_H">1.80</span></td>
<td><span data-selection-price="3.60" data-selection-key="26456117@Result_-_1st_Half.RN_D">3.60</span></td>
<td><span data-selection-price="4.20" data-selection-key="26456117@Result_-_1st_Half.RN_A">4.20</span></td>
</tr>
<tr>
<!-- Period 2 (2nd Half) Result -->
<td><span data-selection-price="2.10" data-selection-key="26456117@Result_-_2nd_Half.RN_H">2.10</span></td>
<td><span data-selection-price="2.80" data-selection-key="26456117@Result_-_2nd_Half.RN_D">2.80</span></td>
<td><span data-selection-price="3.50" data-selection-key="26456117@Result_-_2nd_Half.RN_A">3.50</span></td>
</tr>
</tbody>
</table>
</body>
</html>