1+ import pytest
2+ from fastapi .testclient import TestClient
3+ from uuid import UUID , uuid4
4+ from gs .backend .main import app
5+ from gs .backend .data .enums .transactional import CommandStatus
6+ from gs .backend .data .tables .main_tables import MainCommand
7+
8+ @pytest .fixture
9+ def client ():
10+ return TestClient (app )
11+
12+
13+ @pytest .fixture (autouse = True )
14+ def setup_main_commands (db_session ):
15+ """Setup MainCommand records needed for testing"""
16+ # Create MainCommand entries that will be referenced by Commands
17+ main_commands = [
18+ MainCommand (id = 1 , name = "TestCmd1" , params = None , format = None , data_size = 4 , total_size = 4 ),
19+ MainCommand (id = 2 , name = "TestCmd2" , params = None , format = None , data_size = 4 , total_size = 4 ),
20+ MainCommand (id = 3 , name = "TestCmd3" , params = None , format = None , data_size = 4 , total_size = 4 ),
21+ MainCommand (id = 4 , name = "TestCmd4" , params = None , format = None , data_size = 4 , total_size = 4 ),
22+ MainCommand (id = 5 , name = "TestCmd5" , params = None , format = None , data_size = 4 , total_size = 4 ),
23+ MainCommand (id = 6 , name = "TestCmd6" , params = None , format = None , data_size = 4 , total_size = 4 ),
24+ MainCommand (id = 10 , name = "TestCmd10" , params = None , format = None , data_size = 4 , total_size = 4 ),
25+ MainCommand (id = 11 , name = "TestCmd11" , params = None , format = None , data_size = 4 , total_size = 4 ),
26+ ]
27+ for cmd in main_commands :
28+ db_session .add (cmd )
29+ db_session .commit ()
30+
31+
32+ # ---------------------------------------------Testing the POST endpoint--------------------------------------------- #
33+
34+ def test_create_command_success (client ):
35+ """Test successful creation of a new command"""
36+ payload = {
37+ "status" : CommandStatus .PENDING ,
38+ "type_" : 1 , # Assuming valid MainCommand ID
39+ "params" : "test_params"
40+ }
41+
42+ response = client .post ("/api/v1/mcc/commands/" , json = payload )
43+
44+ assert response .status_code == 200
45+ data = response .json ()
46+ assert "id" in data
47+ assert data ["status" ] == CommandStatus .PENDING
48+ assert data ["type_" ] == 1
49+ assert data ["params" ] == "test_params"
50+ # Validate that id is a valid UUID
51+ UUID (data ["id" ])
52+
53+
54+ def test_create_command_duplicate (client ):
55+ """Test that creating a duplicate command returns 400 error"""
56+ payload = {
57+ "status" : CommandStatus .PENDING ,
58+ "type_" : 2 ,
59+ "params" : "duplicate_test"
60+ }
61+
62+ # Create the first command
63+ response1 = client .post ("/api/v1/mcc/commands/" , json = payload )
64+ assert response1 .status_code == 200
65+
66+ # Attempt to create duplicate command (same payload except id)
67+ response2 = client .post ("/api/v1/mcc/commands/" , json = payload )
68+ assert response2 .status_code == 400
69+ assert response2 .json ()["detail" ] == "Invalid command payload"
70+
71+
72+ def test_create_command_with_null_params (client ):
73+ """Test creating a command with null params"""
74+ payload = {
75+ "status" : CommandStatus .SCHEDULED ,
76+ "type_" : 3 ,
77+ "params" : None
78+ }
79+
80+ response = client .post ("/api/v1/mcc/commands/" , json = payload )
81+
82+ assert response .status_code == 200
83+ data = response .json ()
84+ assert data ["params" ] is None
85+ assert data ["status" ] == CommandStatus .SCHEDULED
86+
87+
88+ def test_create_command_different_status (client ):
89+ """Test creating commands with different status values"""
90+ statuses = [CommandStatus .PENDING , CommandStatus .SCHEDULED , CommandStatus .SENT ]
91+
92+ for idx , status in enumerate (statuses ):
93+ payload = {
94+ "status" : status ,
95+ "type_" : 4 + idx , # Use different type_ to avoid duplicates
96+ "params" : f"params_{ status } "
97+ }
98+
99+ response = client .post ("/api/v1/mcc/commands/" , json = payload )
100+ assert response .status_code == 200
101+ assert response .json ()["status" ] == status
102+
103+
104+ # ---------------------------------------------Testing the DELETE endpoint--------------------------------------------- #
105+
106+ def test_delete_command_success (client ):
107+ """Test successful deletion of an existing command"""
108+ # First create a command to delete
109+ payload = {
110+ "status" : CommandStatus .PENDING ,
111+ "type_" : 10 ,
112+ "params" : "to_be_deleted"
113+ }
114+
115+ create_response = client .post ("/api/v1/mcc/commands/" , json = payload )
116+ assert create_response .status_code == 200
117+ command_id = create_response .json ()["id" ]
118+
119+ # Delete the command
120+ delete_response = client .delete (f"/api/v1/mcc/commands/{ command_id } " )
121+
122+ assert delete_response .status_code == 200
123+ data = delete_response .json ()
124+ assert data ["message" ] == f"Command with id { command_id } deleted successfully"
125+
126+
127+ def test_delete_command_not_found (client ):
128+ """Test deleting a non-existent command raises FileNotFoundError (unhandled exception)"""
129+ # Generate a random UUID that doesn't exist
130+ non_existent_id = uuid4 ()
131+
132+ # The endpoint raises FileNotFoundError which is not caught by FastAPI
133+ # This causes the test client to raise an exception
134+ with pytest .raises (FileNotFoundError , match = f"Command with id { non_existent_id } not found" ):
135+ client .delete (f"/api/v1/mcc/commands/{ non_existent_id } " )
136+
137+
138+ def test_delete_command_invalid_uuid (client ):
139+ """Test deleting with an invalid UUID format returns 422 error"""
140+ invalid_uuid = "not-a-valid-uuid"
141+
142+ response = client .delete (f"/api/v1/mcc/commands/{ invalid_uuid } " )
143+
144+ # FastAPI validation error for invalid UUID format
145+ assert response .status_code == 422
146+
147+
148+ def test_delete_command_twice (client ):
149+ """Test that deleting the same command twice fails on second attempt"""
150+ # Create a command
151+ payload = {
152+ "status" : CommandStatus .PENDING ,
153+ "type_" : 11 ,
154+ "params" : "delete_twice_test"
155+ }
156+
157+ create_response = client .post ("/api/v1/mcc/commands/" , json = payload )
158+ command_id = create_response .json ()["id" ]
159+
160+ # First deletion should succeed
161+ delete_response1 = client .delete (f"/api/v1/mcc/commands/{ command_id } " )
162+ assert delete_response1 .status_code == 200
163+
164+ # Second deletion should raise FileNotFoundError
165+ with pytest .raises (FileNotFoundError , match = f"Command with id { command_id } not found" ):
166+ client .delete (f"/api/v1/mcc/commands/{ command_id } " )
0 commit comments