• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bleedingdeacons / fellowship / 34299413956
90%

Build:
DEFAULT BRANCH: main
Ran 09 Sep 2026 01:33AM UTC
Jobs 1
Files 55
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

09 Sep 2026 01:29AM UTC coverage: 91.718% (-0.5%) from 92.207%
34299413956

push

github

web-flow
fix: decide the device cap by rank instead of a read-then-write (#11)

The per-member cap was count(findByMemberEmail()) >= MAX followed by
create(), with nothing atomic in between, so concurrent enrolments from one
member could all pass the count and land. Each row is, as the class docblock
says, "a credential and a push target" — though each still required a
verified identity that passed the member gate, so this was untidiness rather
than an authorisation bypass. Worth fixing because the cap exists
specifically to bound a retry loop, which is the case most likely to race it.

keepIfWithinCap() is the authoritative check, after the write: it asks how
many live rows the member has at or below this row's id, and the row deletes
itself when that rank exceeds the cap. Rank rather than a re-count because
it is a property of the one row rather than of the table at the moment it is
asked — two of these running at once reach different answers, where a
re-count would have both see the same over-cap total and both delete.

The pre-check stays, so the ordinary case still gets its 409 without writing
a row it then removes.

A hard delete rather than a revoke: the credential was never returned to
anyone, so there is nothing to revoke, and a revoked row would only clutter
the admin list with an enrolment that never happened.

A single-threaded test cannot stage true concurrency, and an earlier version
of this test claimed to and did not — a mutant swapping rank for a plain
re-count passed it. What the test asserts now is the observable difference
the two produce even sequentially: with rank the earliest racer keeps the
slot, with a re-count the last one does. That mutant now fails.

3101 of 3381 relevant lines covered (91.72%)

6.15 hits per line

Coverage Regressions

Lines Coverage ∆ File
14
91.41
-6.42% fellowship/fellowship/src/Devices/WpdbDeviceRepository.php
13
96.6
-1.1% fellowship/fellowship/src/Rest/DeviceAuthController.php
Jobs
ID Job ID Ran Files Coverage
1 34299413956.1 09 Sep 2026 01:33AM UTC 55
91.72
GitHub Action Run
Source Files on build 34299413956
  • Tree
  • List 55
  • Changed 2
  • Source Changed 0
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #34299413956
  • 95d15ba2 on github
  • Prev Build on main (#34001256775)
  • Next Build on main (#34392139581)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc