Repository navigation
test(ui): cover licensing and the admin panel end to end - #7369
Conversation
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
|
Claude finished @luizhf42's task in 43s —— View job Code Review
|
|
/review |
|
Claude finished @gustavosbarreto's task in 3m 14s —— View job Code Review CompleteReviewed 15 files. 2 inline issues posted. Standards: 0 violations, 0 judgement calls. Spec: 0. Correctness: 2. StandardsNo findings. Comments, the commit messages, the e2e fixtures and the Go table test all follow the repo rules and the conventions skills. CorrectnessThe worst defect is in SpecThe Spec axis did not run. The only issue this PR cites is shellhub-io/team#243, and this run can't read that repo. Additional notes
If you've addressed the feedback and want a new review, tag |
4d575c8 to
507c6d4
Compare
|
/review |
|
Claude finished @luizhf42's task in 5m 8s —— View job Code Review CompleteReviewed 17 files. 2 inline issues posted. Standards: 0 violations, 0 judgement calls. Spec: 0. Correctness: 2. StandardsNo findings. The previous round's fixes (b51367f) hold up, and the comments, commit messages, e2e helpers and Go table tests follow the repo rules and conventions skills. CorrectnessThe worst defect is at SpecThe Spec axis did not run. The only issue this PR cites is shellhub-io/team#243, and this run can't read that repo. Additional notes
To request another review round, comment |
507c6d4 to
c39c4e8
Compare
|
/review |
|
Claude finished @luizhf42's task in 5m 31s —— View job Code Review CompleteReviewed 17 files. 2 inline issues posted. Standards: 2 violations, 0 judgement calls. Spec: 0. Correctness: 0. StandardsThe worst violation is at SpecThe Spec axis did not run. The only issue this PR cites is shellhub-io/team#243. This run can't read that repo, and no commit carries a Additional notes
To request another review round, comment |
c39c4e8 to
088198c
Compare
|
/review |
|
Claude finished @luizhf42's task in 4m 4s —— View job Code Review CompleteReviewed 19 files. 1 inline issue posted. Standards: 0 violations, 1 judgement call. Spec: 0. Correctness: 0. StandardsThe only finding is a low-severity judgement call at SpecThe Spec axis did not run. The only issue this PR cites is shellhub-io/team#243. This run can't read that repo, and no commit carries a Additional notes
To request another review round, comment |
088198c to
8273d24
Compare
|
/review |
|
Claude finished @luizhf42's task in 2m 15s —— View job Code Review CompleteReviewed 19 files on two axes: Standards (repo rules, language conventions, tests, code smells) and Correctness (security and runtime defects). No new issues found. The code looks good as-is. The Spec axis did not run, because there is no issue to review against. The only issue the PR cites is shellhub-io/team#243, which this run can't read, and no commit has a |
The period-end cancellation test listed the subscription's draft invoices after the test clock read ready, and threw when there was none. When the test was written, the clock read ready with the final invoice still a draft, so the test finalized it to send `invoice.paid`. Since 2026-10-07 around 18:00 UTC the invoice no longer waits. The cloud e2e job failed this way on master (9a15de8) and on #7369 twice, with no billing change in shellhub or cloud since its last pass at 16:20. In the failed run Stripe sent `invoice.updated`, `invoice.finalized` and `invoice.paid` five seconds after creating the invoice, before `test_clock.ready`, and the server abandoned that `invoice.paid` as it should. Neither the server nor the pinned stripe-cli finalizes invoices, and Stripe's changelog does not mention it, so the cause is on Stripe's side and still unknown. The test now finalizes the invoice only when it is still a draft. The poll for the server's abandon line still fails the test when no `invoice.paid` arrives either way.
8273d24 to
f36c5be
Compare
The license and admin specs need it too, and neither has anything to do with SAML.
`ErrAuthMethodNotAllowed` is the only error carrying `ErrCodeNotImplemented`, and `FromErrServiceToHTTPStatus` had no case for that code, so it fell through to 500. A password sign-in with local authentication turned off answered 500 instead of saying the method is off. The mapping is shared, so cloud's SAML routes now answer 501 too while SAML is disabled. The SAML sign-in spec already documented 501 for that case. 501 rather than 403 because nothing about the caller's permissions is wrong: the instance does not offer the method. `AuthLocalUser` also returned `ErrAuthMethodNotAllowed` when `SystemGet` failed, which would now answer 501 to a database outage. 501 says the method is off, and the API clients do not retry it, so a transient failure would look permanent. `AuthLocalUser` returns the `SystemGet` error as is now, and that error still answers 500. The login and SAML re-auth paths declare 501 now, since the test stacks validate responses and replace an undeclared status. The 501 example shows `internal server error`, because `respond` replaces the message of every status from 500 up. The admin SAML metadata route has no path in the spec.
The license is instance-wide and later specs on the same stack need a valid one, so `afterEach` uploads the license the stack mounts at `/etc/shellhub/license.dat` again. That file is the only valid license the stack has, and there is no endpoint to delete one. `deleteLicenses` accepts any non-zero count because every upload adds a row and the newest one wins. It throws on `DELETE 0`, since the stack always starts with a license. The upload test reloads after the delete so the page fetches the license again. The expired case needs a real license signed by the compiled-in key and more than 7 days past expiry, because inside the grace period the page shows a different message. It comes from the `TEST_EXPIRED_LICENSE` secret through `E2E_EXPIRED_LICENSE`, and the test fails without it, the same as the valid license the stack needs. Pull requests from forks get no secrets and fail there.
The server refuses to turn local authentication off while SAML is off, and to turn SAML off while local authentication is off. So the toggle test enables SAML first, and `afterEach` turns local authentication back on before disabling SAML. It restores with the admin's token, because `disableSaml` signs in with a password and would fail while local authentication is off. `afterEach` returns early when `beforeEach` failed before creating the admin, so the restore does not throw a second error that hides the first.
f36c5be to
488bdd1
Compare

Covers the Playwright cases of Domain 21 (Licensing) and Domain 24 (Admin Panel) in shellhub-io/team#243, and fixes the 500 that the local-auth case ran into. Their
[testcontainers]cases need an enterprise stack inqa.ymland are not part of this PR.Summary
A password sign-in with local authentication turned off answered 500.
ErrAuthMethodNotAllowedcarriesErrCodeNotImplemented, and the converter had no case for that code:FromErrServiceToHTTPStatus(code) case ErrCodeConflict: 409 + case ErrCodeNotImplemented: 501 default: 500The mapping is shared, so cloud's SAML routes now answer 501 too while SAML is off, which is what the SAML sign-in spec already documented.
AuthLocalUseralso returnedErrAuthMethodNotAllowedwhen it could not read the system settings, so a database failure during password sign-in would have answered 501, which the API clients don't retry. It returns the store error now, and that case still answers 500.POST /api/loginand the SAML re-auth path declare501now, because the test stacks validate responses.New specs:
The expired license comes from the new
TEST_EXPIRED_LICENSEsecret, passed to Playwright asE2E_EXPIRED_LICENSE. The test fails without it, locally and in CI. #7375, stacked on this PR, replaces that secret andTEST_LICENSEwith licenses the stack signs for each run.Evidence
TestAuthLocalUser"fails when local authentication is disabled" got 500.After: it gets 501.
AuthLocalUserservice test for a failedSystemGetexpects the store error instead ofErrAuthMethodNotAllowed.license.spec.ts, with an expired license: 4 passedadmin.spec.tsandsaml.spec.ts: 13 passedadmin.spec.ts: 1 passed, 1 skipped (the local-auth test is enterprise only)LicenseGuarddisabled, the no-license test fails on the redirect.Merge Danger
Door: two-way
Blast Radius: small
API clients that sign in with a disabled method now get 501 instead of 500: local login with local auth off, and cloud's SAML routes with SAML off. Until #7375 merges, enterprise e2e in CI needs the
TEST_EXPIRED_LICENSEsecret, and PRs from forks, which get no secrets, fail that test.