Compare commits

..

7 commits

Author SHA1 Message Date
rosslh
bc67ddc40c chore(ci): use Forgejo build and CDN publishing
All checks were successful
Build MapleDeploy Coolify Image / build (push) Successful in 51s
2026-06-19 20:40:54 -04:00
rosslh
c3a4437a8f feat(auth): add dashboard-managed Coolify access 2026-06-19 20:40:54 -04:00
rosslh
c2e2362abc fix(dns): use Canadian Shield DNS defaults 2026-06-19 20:40:54 -04:00
rosslh
fdaf60da7c fix(telemetry): disable upstream telemetry 2026-06-19 20:40:54 -04:00
rosslh
3b4aa40eb0 fix(update): use MapleDeploy CDN and registry artifacts 2026-06-19 20:40:54 -04:00
rosslh
f1e60bac53 style(theme): apply MapleDeploy palette and fonts 2026-06-19 20:40:54 -04:00
rosslh
3b45835909 feat(branding): apply MapleDeploy UI branding 2026-06-19 20:40:54 -04:00
2 changed files with 0 additions and 97 deletions

View file

@ -6,7 +6,6 @@ on:
paths-ignore:
- "*.md"
- ".github/**"
- "templates/**"
env:
REGISTRY: forgejo.mapledeploy.ca

View file

@ -1,96 +0,0 @@
<?php
use Illuminate\Support\Facades\Http;
beforeEach(function () {
Http::fake([
'discord.com/*' => Http::response([], 204),
]);
});
it('rejects feedback with missing content', function () {
$response = $this->postJson('/api/feedback', []);
$response->assertStatus(422)
->assertJsonValidationErrors('content');
});
it('rejects feedback with content too short', function () {
$response = $this->postJson('/api/feedback', ['content' => 'short']);
$response->assertStatus(422)
->assertJsonValidationErrors('content');
});
it('rejects feedback with content too long', function () {
$response = $this->postJson('/api/feedback', ['content' => str_repeat('a', 2001)]);
$response->assertStatus(422)
->assertJsonValidationErrors('content');
});
it('rejects feedback with non-string content', function () {
$response = $this->postJson('/api/feedback', ['content' => ['array', 'value']]);
$response->assertStatus(422)
->assertJsonValidationErrors('content');
});
it('accepts valid feedback and forwards to discord with mentions disabled', function () {
config()->set('constants.webhooks.feedback_discord_webhook', 'https://discord.com/api/webhooks/test');
$response = $this->postJson('/api/feedback', [
'content' => 'This is a valid feedback message for testing purposes.',
]);
$response->assertStatus(200)
->assertJson(['message' => 'Feedback sent.']);
Http::assertSent(function ($request) {
return $request->url() === 'https://discord.com/api/webhooks/test'
&& $request['content'] === 'This is a valid feedback message for testing purposes.'
&& $request['allowed_mentions'] === ['parse' => []];
});
});
it('does not forward to discord when webhook url is not configured', function () {
config()->set('constants.webhooks.feedback_discord_webhook', null);
$response = $this->postJson('/api/feedback', [
'content' => 'This is a valid feedback message for testing purposes.',
]);
$response->assertStatus(200);
Http::assertNothingSent();
});
it('throttles feedback endpoint after 3 requests per minute', function () {
config()->set('constants.webhooks.feedback_discord_webhook', null);
for ($i = 0; $i < 3; $i++) {
$response = $this->postJson('/api/feedback', [
'content' => "Valid feedback message number {$i} for testing.",
]);
$response->assertStatus(200);
}
$response = $this->postJson('/api/feedback', [
'content' => 'This fourth request should be throttled.',
]);
$response->assertStatus(429);
});
it('disables discord mention parsing regardless of content', function () {
config()->set('constants.webhooks.feedback_discord_webhook', 'https://discord.com/api/webhooks/test');
$response = $this->postJson('/api/feedback', [
'content' => 'User feedback includes an @everyone style phrase and a link https://example.com for reference.',
]);
$response->assertStatus(200);
Http::assertSent(function ($request) {
return $request['allowed_mentions'] === ['parse' => []];
});
});