|
1 | | -# 🚀 PCB Backend API |
| 1 | +# 🚀 PCB Backend API - Unit Testing Branch |
2 | 2 |
|
3 | | -Backend service yang handal untuk sistem IoT PCB, dibangun menggunakan **FastAPI** (Python). Proyek ini menyediakan API untuk manajemen perangkat, kontrol relay secara real-time via **MQTT**, penyimpanan log sensor, dan autentikasi pengguna yang aman. |
| 3 | +> **Note**: This is the dedicated branch for **setup and validation of unit tests**. |
| 4 | +> If you are looking for the production documentation, please switch to the `main` branch. |
4 | 5 |
|
5 | | ---- |
6 | | - |
7 | | -## ✨ Fitur Utama |
8 | | - |
9 | | -* **⚡ High Performance API**: Dibangun di atas FastAPI (Asynchronous). |
10 | | -* **🔐 Secure Authentication**: Terintegrasi penuh dengan **Firebase Auth** (Token Validation). |
11 | | -* **📡 Real-time Control**: Kontrol perangkat (Lampu, Pompa, dll) menggunakan protokol **MQTT**. |
12 | | -* **🗄️ Database Power**: Menggunakan **PostgreSQL** untuk data persisten yang handal. |
13 | | -* **🛡️ Rate Limiting**: Perlindungan terhadap spam/brute-force menggunakan **Redis**. |
14 | | -* **🐳 Dockerized**: Mudah di-deploy menggunakan Docker Compose. |
15 | | -* **🤖 Auto Register**: Mekanisme pendaftaran otomatis untuk perangkat keras (ESP32) yang valid. |
| 6 | +This branch focuses on ensuring code stability and reliability using `pytest` with a **Mocked Environment** strategy. |
16 | 7 |
|
17 | 8 | --- |
18 | 9 |
|
19 | | -## 🛠️ Teknologi yang Digunakan |
| 10 | +## 🧪 Testing Features |
| 11 | +This branch implements a robust testing suite that covers: |
| 12 | +* **Auto-Registration**: Validates ESP32 device registration flow. |
| 13 | +* **Device Claiming**: Ensures user ownership claim logic works safely. |
| 14 | +* **Mqtt Controls**: Mocks MQTT publishing to verify command logic without real broker connection. |
| 15 | +* **Rate Limiting**: Tests protection mechanisms against spamming. |
20 | 16 |
|
21 | | -* **Bahasa**: Python 3.11+ |
22 | | -* **Framework**: FastAPI + Uvicorn |
23 | | -* **Database**: PostgreSQL |
24 | | -* **Cache & Limiter**: Redis |
25 | | -* **Messaging**: Paho MQTT |
26 | | -* **Auth**: Firebase Admin SDK |
27 | | -* **DevOps**: Docker & Docker Compose |
| 17 | +### Why Mocking? |
| 18 | +We use `mock` and `patch` to isolate the backend from external dependencies: |
| 19 | +1. **NO Real Database**: Uses `sqlite:///:memory:` for fast, clean-slate testing. |
| 20 | +2. **NO Real MQTT**: Connection is intercepted to prevent network errors. |
| 21 | +3. **NO Real Redis**: Rate limits are bypassed or mocked for consistent results. |
28 | 22 |
|
29 | 23 | --- |
30 | 24 |
|
31 | | -## 📋 Prasyarat |
32 | | - |
33 | | -Sebelum memulai, pastikan Anda telah menginstal: |
34 | | - |
35 | | -1. **Docker** & **Docker Compose** (Sangat Disarankan) |
36 | | -2. **Git** |
37 | | -3. Akun **Firebase** (untuk Authentication dan `serviceAccountKey.json`) |
| 25 | +## 📋 Prerequisites |
| 26 | +Ensure you have the following installed: |
| 27 | +1. **Python 3.11+** |
| 28 | +2. **Virtual Environment (`venv`)** |
38 | 29 |
|
39 | 30 | --- |
40 | 31 |
|
41 | | -## 🚀 Instalasi & Menjalankan (Docker) |
42 | | - |
43 | | -Cara termudah untuk menjalankan proyek ini adalah menggunakan Docker Compose. |
| 32 | +## 🚀 Setup & Installation |
44 | 33 |
|
45 | | -### 1. Clone Repository |
| 34 | +### 1. Clone & Switch Branch |
46 | 35 | ```bash |
47 | | -git clone https://github.com/username/project-ini.git |
| 36 | +git clone https://github.com/username/API-PCB.git |
48 | 37 | cd API-PCB |
| 38 | +git checkout unit-testing |
49 | 39 | ``` |
50 | 40 |
|
51 | | -### 2. Konfigurasi Firebase |
52 | | -Simpan file kredensial Firebase Admin SDK Anda ke lokasi berikut: |
| 41 | +### 2. Create Virtual Environment |
53 | 42 | ```bash |
54 | | -app/serviceAccountKey.json |
| 43 | +python -m venv .venv |
| 44 | +source .venv/bin/activate # On Windows: .venv\Scripts\activate |
55 | 45 | ``` |
56 | | -> **Penting**: File ini bersifat rahasia. Jangan pernah commit file ini ke repository publik! |
57 | | -
|
58 | | -### 3. Konfigurasi Environment Variable |
59 | | -Buat file `.env` di root folder dan sesuaikan isinya: |
60 | | - |
61 | | -```env |
62 | | -# Database Credentials |
63 | | -DB_USER=iot_user |
64 | | -DB_PASSWORD=iot_password |
65 | | -DB_NAME=iot_db |
66 | 46 |
|
67 | | -# Redis URL (Default Docker) |
68 | | -REDIS_URL=redis://redis:6379/0 |
69 | | -
|
70 | | -# (Opsional) Lainnya sesuai kebutuhan |
71 | | -``` |
72 | | - |
73 | | -### 4. Jalankan Aplikasi |
| 47 | +### 3. Install Requirements |
| 48 | +Install main dependencies + testing libraries (`pytest`, `httpx`, etc.): |
74 | 49 | ```bash |
75 | | -docker-compose up -d --build |
| 50 | +pip install -r requirements.txt |
76 | 51 | ``` |
77 | | -Aplikasi akan berjalan di: |
78 | | -* **API**: `http://localhost:8006` |
79 | | -* **Swagger Docs**: `http://localhost:8006/docs` |
80 | | -* **Redoc**: `http://localhost:8006/redoc` |
81 | 52 |
|
82 | 53 | --- |
83 | 54 |
|
84 | | -## 📡 Dokumentasi API |
85 | | - |
86 | | -Seluruh endpoint membutuhkan **Header Authorization** (Bearer Token dari Firebase Client), kecuali endpoint *Auto Register*. |
87 | | - |
88 | | -### 📱 1. Device Management (`/api/devices`) |
89 | | - |
90 | | -| Method | Endpoint | Deskripsi | Limit Rate | |
91 | | -| :--- | :--- | :--- | :--- | |
92 | | -| `GET` | `/my-devices` | Mengambil daftar alat milik user. | 20/menit | |
93 | | -| `POST` | `/claim` | Mengklaim alat baru menggunakan ID & PIN. | 5/menit | |
94 | | -| `PUT` | `/{device_id}` | Mengubah nama alat. | 10/menit | |
95 | | -| `DELETE` | `/{device_id}` | Menghapus alat dari akun (Unclaim). | 5/menit | |
96 | | - |
97 | | -### 🎛️ 2. Device Control (`/api/devices`) |
| 55 | +## ⚙️ Running Tests |
98 | 56 |
|
99 | | -| Method | Endpoint | Deskripsi | Parameter | |
100 | | -| :--- | :--- | :--- | :--- | |
101 | | -| `POST` | `/control-relay` | Mengirim perintah ON/OFF ke alat via MQTT. | `device_id`, `relay_name`, `state` (bool) | |
102 | | -| `POST` | `/auto-register` | (Internal) Pendaftaran otomatis oleh ESP32. | *Requires Factory Secret* | |
| 57 | +### Standard Run |
| 58 | +Simply execute `pytest` from the root directory. It will automatically load configuration from `tests/conftest.py`. |
103 | 59 |
|
104 | | -> **Relay Mapping**: |
105 | | -> * `relay_1` -> Topik `.../cmd/lampu` |
106 | | -> * `relay_2` -> Topik `.../cmd/pompa_minum` |
107 | | -> * `relay_3` -> Topik `.../cmd/pompa_siram` |
108 | | -
|
109 | | -### 📊 3. Sensor Logs (`/api/logs`) |
110 | | - |
111 | | -| Method | Endpoint | Deskripsi | |
112 | | -| :--- | :--- | :--- | |
113 | | -| `GET` | `/{device_id}` | Mengambil data log sensor dari alat tertentu. | |
114 | | - |
115 | | ---- |
116 | | - |
117 | | -## 📂 Struktur Proyek |
| 60 | +```bash |
| 61 | +pytest |
| 62 | +``` |
118 | 63 |
|
| 64 | +**Expected Output (Greens):** |
119 | 65 | ``` |
120 | | -API-PCB/ |
121 | | -├── app/ |
122 | | -│ ├── api/ # Router & Logic API per versi (v1) |
123 | | -│ │ └── v1/ |
124 | | -│ │ ├── auth.py # Helper Auth Firebase |
125 | | -│ │ ├── devices.py # Endpoint Device & Control |
126 | | -│ │ └── logs.py # Endpoint Logs |
127 | | -│ ├── core/ # Konfigurasi Database & Global |
128 | | -│ ├── crud/ # Operasi Database (Create, Read, etc) |
129 | | -│ ├── models/ # Schema Database (SQLAlchemy) |
130 | | -│ ├── mqtt/ # Client & Handler MQTT |
131 | | -│ ├── schemas/ # Validasi Data (Pydantic) |
132 | | -│ ├── main.py # Entry Point Aplikasi (Lifespan, Startup) |
133 | | -│ └── serviceAccountKey.json # (WAJIB ADA) Kunci Firebase |
134 | | -├── docker-compose.yml # Orkestrasi Container (App, DB, Redis) |
135 | | -├── dockerfile # Definisi Image App |
136 | | -├── requirements.txt # Dependensi Python |
137 | | -├── test_client.py # Script Python untuk mencoba API manual |
138 | | -└── readme.md # Dokumentasi ini |
| 66 | +tests/test_devices.py ...... [100%] |
| 67 | +================= 6 passed in 0.xxs ================= |
139 | 68 | ``` |
140 | 69 |
|
141 | | ---- |
| 70 | +### Run with Detailed Output |
| 71 | +To see printed logs (e.g. "Mock MQTT Publish"): |
| 72 | +```bash |
| 73 | +pytest -s |
| 74 | +``` |
142 | 75 |
|
143 | | -## 🧪 Testing Manual |
| 76 | +### Run Specific Test |
| 77 | +```bash |
| 78 | +pytest tests/test_devices.py::test_auto_register_success |
| 79 | +``` |
144 | 80 |
|
145 | | -Terdapat script `test_client.py` untuk mencoba API tanpa frontend. |
| 81 | +--- |
146 | 82 |
|
147 | | -1. Pastikan `requests` terinstall: `pip install requests` |
148 | | -2. Edit `test_client.py`: |
149 | | - * Masukkan `FIREBASE_WEB_API_KEY` (dari Firebase Console). |
150 | | - * Masukkan credentials user dummy (Email/Pass). |
151 | | - * Set `DEVICE_ID` target. |
152 | | -3. Jalankan: |
153 | | - ```bash |
154 | | - python test_client.py |
155 | | - ``` |
| 83 | +## 📂 Test Structure |
| 84 | +* **`tests/`**: Contains all test modules. |
| 85 | + * **`conftest.py`**: The heart of the test setup. Contains: |
| 86 | + * `load_dotenv()`: Auto-load `.env` variables. |
| 87 | + * `mock_external_services`: Fixture to patch MQTT, Redis, Firebase. |
| 88 | + * `db_session`: Fixture to create/drop pure in-memory SQLite tables. |
| 89 | + * **`test_devices.py`**: Functional tests for device endpoints. |
156 | 90 |
|
157 | 91 | --- |
158 | 92 |
|
159 | | -## 🤝 Kontribusi |
160 | | - |
161 | | -Pull requests dipersilakan. Untuk perubahan besar, harap buka issue terlebih dahulu untuk mendiskusikan apa yang ingin Anda ubah. |
| 93 | +## 🔧 Troubleshooting |
| 94 | +If tests fail: |
| 95 | +1. **Check `.venv`**: Ensure it's active (`source .venv/bin/activate`). |
| 96 | +2. **Requirements**: Run `pip install -r requirements.txt` again. |
| 97 | +3. **Environment**: `conftest.py` should handle env vars, but ensure `.env` file exists if your app code critically depends on checking file existence. |
162 | 98 |
|
163 | 99 | --- |
164 | 100 |
|
165 | | -**Happy Coding!** 🚀 |
| 101 | +**Happy Testing!** 🧪 |
0 commit comments