@@ -566,6 +566,88 @@ public function testAlertRuleFieldsArePresent(): void
566566 ->assertJsonPath ('data.attributes.notes ' , 'Check port status ' );
567567 }
568568
569+ public function testAdminCanCreateAlertRule (): void
570+ {
571+ $ user = User::factory ()->admin ()->create ();
572+ Sanctum::actingAs ($ user );
573+
574+ $ builder = [
575+ 'condition ' => 'AND ' ,
576+ 'rules ' => [['id ' => 'devices.status ' , 'operator ' => 'equal ' , 'value ' => 0 ]],
577+ ];
578+ $ extra = ['mute ' => false , 'count ' => '-1 ' , 'delay ' => 300 , 'interval ' => 300 ];
579+ $ query = 'devices.status = 0 ' ;
580+
581+ $ response = $ this ->postJsonApi ('/api/v1/alert-rules ' , [
582+ 'name ' => 'Device Unreachable ' ,
583+ 'severity ' => 'critical ' ,
584+ 'isEnabled ' => true ,
585+ 'procedure ' => 'Page on-call ' ,
586+ 'notes ' => 'Triggered when ICMP fails for 5m ' ,
587+ 'isInverted ' => false ,
588+ 'builder ' => $ builder ,
589+ 'extra ' => $ extra ,
590+ 'query ' => $ query ,
591+ ]);
592+
593+ $ response ->assertStatus (201 )
594+ ->assertJsonPath ('data.attributes.name ' , 'Device Unreachable ' )
595+ ->assertJsonPath ('data.attributes.severity ' , 'critical ' )
596+ ->assertJsonPath ('data.attributes.isEnabled ' , true )
597+ ->assertJsonPath ('data.attributes.procedure ' , 'Page on-call ' )
598+ ->assertJsonPath ('data.attributes.notes ' , 'Triggered when ICMP fails for 5m ' )
599+ ->assertJsonPath ('data.attributes.isInverted ' , false )
600+ ->assertJsonPath ('data.attributes.builder ' , $ builder )
601+ ->assertJsonPath ('data.attributes.query ' , $ query );
602+
603+ $ created = AlertRule::where ('name ' , 'Device Unreachable ' )->firstOrFail ();
604+ $ this ->assertSame ($ builder , $ created ->builder );
605+ $ this ->assertSame ($ extra , $ created ->extra );
606+ $ this ->assertSame ($ query , $ created ->query );
607+ $ this ->assertSame ('Page on-call ' , $ created ->proc );
608+ $ this ->assertSame (0 , (int ) $ created ->disabled );
609+ $ this ->assertSame (0 , (int ) $ created ->invert_map );
610+ }
611+
612+ public function testAlertRuleCreateUsesDefaultsForOptionalFields (): void
613+ {
614+ $ user = User::factory ()->admin ()->create ();
615+ Sanctum::actingAs ($ user );
616+
617+ $ this ->postJsonApi ('/api/v1/alert-rules ' , [
618+ 'name ' => 'Bare Minimum Rule ' ,
619+ 'severity ' => 'warning ' ,
620+ 'isEnabled ' => true ,
621+ ])->assertStatus (201 );
622+
623+ $ created = AlertRule::where ('name ' , 'Bare Minimum Rule ' )->firstOrFail ();
624+ $ this ->assertSame ([], $ created ->builder );
625+ $ this ->assertSame ([], $ created ->extra );
626+ $ this ->assertSame ('' , $ created ->query );
627+ }
628+
629+ public function testAlertRuleCreateRejectsMissingRequiredFields (): void
630+ {
631+ $ user = User::factory ()->admin ()->create ();
632+ Sanctum::actingAs ($ user );
633+
634+ $ this ->postJsonApi ('/api/v1/alert-rules ' , [
635+ 'notes ' => 'no name, no severity ' ,
636+ ])->assertStatus (422 );
637+ }
638+
639+ public function testReadOnlyUserCannotCreateAlertRule (): void
640+ {
641+ $ user = User::factory ()->read ()->create ();
642+ Sanctum::actingAs ($ user );
643+
644+ $ this ->postJsonApi ('/api/v1/alert-rules ' , [
645+ 'name ' => 'Should Be Rejected ' ,
646+ 'severity ' => 'warning ' ,
647+ 'isEnabled ' => true ,
648+ ])->assertStatus (403 );
649+ }
650+
569651 public function testAdminCanUpdateAlertRuleSeverity (): void
570652 {
571653 $ user = User::factory ()->admin ()->create ();
@@ -1034,6 +1116,23 @@ public function testAlertScheduleFieldsArePresent(): void
10341116 ->assertJsonPath ('data.attributes.notes ' , 'Router upgrade ' );
10351117 }
10361118
1119+ public function testAdminCanCreateAlertSchedule (): void
1120+ {
1121+ $ user = User::factory ()->admin ()->create ();
1122+ Sanctum::actingAs ($ user );
1123+
1124+ $ this ->postJsonApi ('/api/v1/alert-schedules ' , [
1125+ 'title ' => 'Weekend Maintenance ' ,
1126+ 'notes ' => 'Scheduled router upgrade ' ,
1127+ 'isRecurring ' => false ,
1128+ ])->assertStatus (201 )
1129+ ->assertJsonPath ('data.attributes.title ' , 'Weekend Maintenance ' )
1130+ ->assertJsonPath ('data.attributes.notes ' , 'Scheduled router upgrade ' )
1131+ ->assertJsonPath ('data.attributes.isRecurring ' , false );
1132+
1133+ $ this ->assertDatabaseHas ('alert_schedule ' , ['title ' => 'Weekend Maintenance ' ]);
1134+ }
1135+
10371136 public function testAdminCanDeleteAlertSchedule (): void
10381137 {
10391138 $ user = User::factory ()->admin ()->create ();
@@ -1097,6 +1196,23 @@ public function testAlertTransportFieldsArePresent(): void
10971196 ->assertJsonPath ('data.attributes.isDefault ' , true );
10981197 }
10991198
1199+ public function testAdminCanCreateAlertTransport (): void
1200+ {
1201+ $ user = User::factory ()->admin ()->create ();
1202+ Sanctum::actingAs ($ user );
1203+
1204+ $ this ->postJsonApi ('/api/v1/alert-transports ' , [
1205+ 'name ' => 'Email Alerts ' ,
1206+ 'category ' => 'mail ' ,
1207+ 'isDefault ' => true ,
1208+ ])->assertStatus (201 )
1209+ ->assertJsonPath ('data.attributes.name ' , 'Email Alerts ' )
1210+ ->assertJsonPath ('data.attributes.category ' , 'mail ' )
1211+ ->assertJsonPath ('data.attributes.isDefault ' , true );
1212+
1213+ $ this ->assertDatabaseHas ('alert_transports ' , ['transport_name ' => 'Email Alerts ' ]);
1214+ }
1215+
11001216 public function testAdminCanDeleteAlertTransport (): void
11011217 {
11021218 $ user = User::factory ()->admin ()->create ();
@@ -1163,6 +1279,25 @@ public function testServiceTemplateFieldsArePresent(): void
11631279 ->assertJsonPath ('data.attributes.description ' , 'Monitor DNS servers ' );
11641280 }
11651281
1282+ public function testAdminCanCreateServiceTemplate (): void
1283+ {
1284+ $ user = User::factory ()->admin ()->create ();
1285+ Sanctum::actingAs ($ user );
1286+
1287+ $ this ->postJsonApi ('/api/v1/service-templates ' , [
1288+ 'name ' => 'HTTP Monitor ' ,
1289+ 'check ' => 'http ' ,
1290+ 'category ' => 'static ' ,
1291+ 'description ' => 'Monitor HTTP endpoints ' ,
1292+ ])->assertStatus (201 )
1293+ ->assertJsonPath ('data.attributes.name ' , 'HTTP Monitor ' )
1294+ ->assertJsonPath ('data.attributes.check ' , 'http ' )
1295+ ->assertJsonPath ('data.attributes.category ' , 'static ' )
1296+ ->assertJsonPath ('data.attributes.description ' , 'Monitor HTTP endpoints ' );
1297+
1298+ $ this ->assertDatabaseHas ('service_templates ' , ['name ' => 'HTTP Monitor ' ]);
1299+ }
1300+
11661301 public function testAdminCanDeleteServiceTemplate (): void
11671302 {
11681303 $ user = User::factory ()->admin ()->create ();
0 commit comments