FrancisGOS commited on
Commit
fb24ad1
2 Parent(s): c6a9f21 7ea3581

<Merge>: Merge main fix bug

Browse files
.coverage DELETED
Binary file (53.2 kB)
 
.github/workflows/test.yml CHANGED
@@ -18,7 +18,6 @@ jobs:
18
  python-version: "3.8"
19
  - name: install dependency
20
  run: |
21
- git lfs checkout
22
  pip install -r app/requirements.txt
23
  - name: Run test
24
  run: pytest
 
18
  python-version: "3.8"
19
  - name: install dependency
20
  run: |
 
21
  pip install -r app/requirements.txt
22
  - name: Run test
23
  run: pytest
app/__init__.py CHANGED
@@ -11,8 +11,8 @@ from firebase_admin import firestore
11
  from neo4j import GraphDatabase
12
 
13
 
14
- logger = logging.getLogger("uvicorn")
15
- logger.setLevel(logging.INFO)
16
 
17
 
18
  load_dotenv()
 
11
  from neo4j import GraphDatabase
12
 
13
 
14
+ logging.basicConfig(level=logging.DEBUG)
15
+ logger = logging.getLogger(__name__)
16
 
17
 
18
  load_dotenv()
app/dependencies.py CHANGED
@@ -2,6 +2,7 @@ from fastapi import Depends, HTTPException, status
2
  from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
3
  from firebase_admin import auth
4
  from firebase_admin.auth import ExpiredIdTokenError, InvalidIdTokenError
 
5
  from . import db
6
 
7
  security = HTTPBearer()
@@ -15,19 +16,19 @@ def get_current_user(
15
  user_doc_ref = db.collection("user").document(payload["sub"]).get()
16
  if not user_doc_ref.exists:
17
  raise HTTPException(status_code=400, detail="User profile not found")
18
- except ExpiredIdTokenError as e:
19
  raise HTTPException(
20
  status_code=status.HTTP_401_UNAUTHORIZED,
21
  detail="Token expired",
22
  headers={"WWW-Authenticate": "Bearer"},
23
  )
24
- except InvalidIdTokenError as e:
25
  raise HTTPException(
26
  status_code=status.HTTP_401_UNAUTHORIZED,
27
  detail="Invalid token",
28
  headers={"WWW-Authenticate": "Bearer"},
29
  )
30
- except ValueError as e:
31
  raise HTTPException(
32
  status_code=status.HTTP_401_UNAUTHORIZED,
33
  detail="Invalid token",
@@ -35,6 +36,8 @@ def get_current_user(
35
  )
36
 
37
  except Exception as e:
 
 
38
  raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
39
 
40
  return payload
 
2
  from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
3
  from firebase_admin import auth
4
  from firebase_admin.auth import ExpiredIdTokenError, InvalidIdTokenError
5
+ from app import logger
6
  from . import db
7
 
8
  security = HTTPBearer()
 
16
  user_doc_ref = db.collection("user").document(payload["sub"]).get()
17
  if not user_doc_ref.exists:
18
  raise HTTPException(status_code=400, detail="User profile not found")
19
+ except ExpiredIdTokenError:
20
  raise HTTPException(
21
  status_code=status.HTTP_401_UNAUTHORIZED,
22
  detail="Token expired",
23
  headers={"WWW-Authenticate": "Bearer"},
24
  )
25
+ except InvalidIdTokenError:
26
  raise HTTPException(
27
  status_code=status.HTTP_401_UNAUTHORIZED,
28
  detail="Invalid token",
29
  headers={"WWW-Authenticate": "Bearer"},
30
  )
31
+ except ValueError:
32
  raise HTTPException(
33
  status_code=status.HTTP_401_UNAUTHORIZED,
34
  detail="Invalid token",
 
36
  )
37
 
38
  except Exception as e:
39
+ logger.info(e)
40
+ logger.error(e)
41
  raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
42
 
43
  return payload
app/main.py CHANGED
@@ -4,6 +4,7 @@ from fastapi.responses import RedirectResponse
4
  from app.graphdb.main import insert2PersonAndSetFriend, deleteFriend
5
  from .routers import image, video, friend_request, me
6
 
 
7
 
8
  app = FastAPI()
9
 
@@ -23,3 +24,7 @@ def hello():
23
  async def test():
24
  await insert2PersonAndSetFriend("1", "2")
25
  await deleteFriend("1", "2")
 
 
 
 
 
4
  from app.graphdb.main import insert2PersonAndSetFriend, deleteFriend
5
  from .routers import image, video, friend_request, me
6
 
7
+ import uvicorn
8
 
9
  app = FastAPI()
10
 
 
24
  async def test():
25
  await insert2PersonAndSetFriend("1", "2")
26
  await deleteFriend("1", "2")
27
+
28
+
29
+ if __name__ == "__main__":
30
+ uvicorn.run(app, host="0.0.0.0", port=8000)
app/routers/video.py CHANGED
@@ -15,21 +15,22 @@ from fastapi import (
15
  BackgroundTasks,
16
  status,
17
  )
18
- import requests
 
19
  from app import supabase
20
  from app.dependencies import get_current_user
21
  from app.routers.image import inferenceImage
 
22
 
23
  router = APIRouter(prefix="/video", tags=["Video"])
24
 
25
 
26
- @router.post("/{artifactId}")
27
  async def handleVideoRequest(
28
- artifactId: str,
29
  file: UploadFile,
30
  background_tasks: BackgroundTasks,
31
  threshold: float = 0.3,
32
- _=Depends(get_current_user),
33
  ):
34
  if re.search("^video\/", file.content_type) is None:
35
  raise HTTPException(
@@ -38,12 +39,15 @@ async def handleVideoRequest(
38
  )
39
 
40
  try:
 
 
41
  id = str(now())
 
42
  os.mkdir(id)
43
  async with aiofiles.open(os.path.join(id, "input.mp4"), "wb") as out_file:
44
  while content := await file.read(1024):
45
  await out_file.write(content)
46
- background_tasks.add_task(inferenceVideo, artifactId, id, threshold)
47
  return id + ".mp4"
48
  except ValueError as err:
49
  print(err)
@@ -145,7 +149,42 @@ async def inferenceVideo(artifactId: str, inputDir: str, threshold: float):
145
 
146
 
147
  def updateArtifact(artifactId: str, body):
148
- url = "https://firebasetot.onrender.com/artifacts/" + artifactId
149
- payload = json.dumps(body)
150
- headers = {"Content-Type": "application/json"}
151
- requests.request("PATCH", url, headers=headers, data=payload)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  BackgroundTasks,
16
  status,
17
  )
18
+ from firebase_admin import messaging
19
+ from app import db
20
  from app import supabase
21
  from app.dependencies import get_current_user
22
  from app.routers.image import inferenceImage
23
+ from google.cloud.firestore_v1.base_query import FieldFilter
24
 
25
  router = APIRouter(prefix="/video", tags=["Video"])
26
 
27
 
28
+ @router.post("")
29
  async def handleVideoRequest(
 
30
  file: UploadFile,
31
  background_tasks: BackgroundTasks,
32
  threshold: float = 0.3,
33
+ user=Depends(get_current_user),
34
  ):
35
  if re.search("^video\/", file.content_type) is None:
36
  raise HTTPException(
 
39
  )
40
 
41
  try:
42
+ if user["sub"] is None:
43
+ return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="User not found")
44
  id = str(now())
45
+ _, artifact_ref = db.collection("artifacts").add({"name": id + ".mp4", "status": "pending"})
46
  os.mkdir(id)
47
  async with aiofiles.open(os.path.join(id, "input.mp4"), "wb") as out_file:
48
  while content := await file.read(1024):
49
  await out_file.write(content)
50
+ background_tasks.add_task(inferenceVideo, artifact_ref.id, id, threshold)
51
  return id + ".mp4"
52
  except ValueError as err:
53
  print(err)
 
149
 
150
 
151
  def updateArtifact(artifactId: str, body):
152
+ artifact_snapshot = db.collection("artifacts").document(artifactId)
153
+ if not artifact_snapshot.exists:
154
+ artifact_snapshot.update(body)
155
+ sendMessage(artifactId)
156
+ # This function cannot be automation test because the requirement of another device to receive notification
157
+ def sendMessage(artifactId: str, message: str = None):
158
+ token = []
159
+ artifact = db.collection("artifacts").document(artifactId).get()
160
+ if not artifact.exists:
161
+ return
162
+ user_ref = db.collection("user").where(filter=FieldFilter("artifacts", "array-contains", "artifacts/" + artifactId))
163
+ for user in user_ref:
164
+ token.append(user.get().to_dict()['deviceId'])
165
+ if message is not None:
166
+ messaging.MulticastMessage(data={"notification": {
167
+ "title": message,
168
+ "body":
169
+ "Video " +
170
+ artifact.name +
171
+ " has done inference. Click here to see the video",
172
+ },}, android=messaging.AndroidConfig(
173
+ notification=messaging.AndroidNotification(
174
+ icon='stock_ticker_update',
175
+ color='#f45342'
176
+ ),))
177
+ else:
178
+ messaging.MulticastMessage(data={"notification": {
179
+ "title": "Video " + artifact.name + " has done inference.",
180
+ "body":
181
+ "Video " +
182
+ artifact.name +
183
+ " has done inference. Click here to see the video",
184
+ },}, android=messaging.AndroidConfig(
185
+ notification=messaging.AndroidNotification(
186
+ icon='stock_ticker_update',
187
+ color='#f45342'
188
+ ),))
189
+ response = messaging.send_multicast(message)
190
+ return response.success_count
coverage.xml CHANGED
@@ -1,12 +1,12 @@
1
  <?xml version="1.0" ?>
2
- <coverage version="7.2.2" timestamp="1699373732964" lines-valid="576" lines-covered="466" line-rate="0.809" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
3
  <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.2.2 -->
4
  <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
5
  <sources>
6
  <source>D:\SE113.O12_KCPM\app</source>
7
  </sources>
8
  <packages>
9
- <package name="." line-rate="0.9157" branch-rate="0" complexity="0">
10
  <classes>
11
  <class name="__init__.py" filename="__init__.py" complexity="0" line-rate="0.963" branch-rate="0">
12
  <methods/>
@@ -48,7 +48,7 @@
48
  <line number="170" hits="1"/>
49
  </lines>
50
  </class>
51
- <class name="dependencies.py" filename="dependencies.py" complexity="0" line-rate="0.9048" branch-rate="0">
52
  <methods/>
53
  <lines>
54
  <line number="1" hits="1"/>
@@ -56,71 +56,57 @@
56
  <line number="3" hits="1"/>
57
  <line number="4" hits="1"/>
58
  <line number="5" hits="1"/>
59
- <line number="7" hits="1"/>
60
- <line number="10" hits="1"/>
61
- <line number="13" hits="1"/>
62
- <line number="14" hits="1"/>
63
- <line number="15" hits="1"/>
64
- <line number="16" hits="1"/>
65
- <line number="17" hits="1"/>
66
- <line number="18" hits="1"/>
67
- <line number="19" hits="0"/>
68
- <line number="24" hits="1"/>
69
- <line number="25" hits="1"/>
70
- <line number="30" hits="1"/>
71
- <line number="31" hits="0"/>
72
- <line number="37" hits="1"/>
73
- <line number="38" hits="1"/>
74
- <line number="40" hits="1"/>
75
- </lines>
76
- </class>
77
- <class name="main.py" filename="main.py" complexity="0" line-rate="0.7647" branch-rate="0">
78
- <methods/>
79
- <lines>
80
- <line number="1" hits="1"/>
81
- <line number="2" hits="1"/>
82
- <line number="4" hits="1"/>
83
- <line number="5" hits="1"/>
84
  <line number="8" hits="1"/>
85
- <line number="10" hits="1"/>
86
  <line number="11" hits="1"/>
87
- <line number="12" hits="1"/>
88
- <line number="13" hits="1"/>
89
- <line number="16" hits="1"/>
90
- <line number="17" hits="1"/>
91
  <line number="18" hits="0"/>
92
  <line number="19" hits="0"/>
93
- <line number="22" hits="1"/>
94
- <line number="23" hits="1"/>
95
- <line number="24" hits="0"/>
96
  <line number="25" hits="0"/>
 
 
 
 
 
 
 
 
97
  </lines>
98
  </class>
99
- <class name="test_main.py" filename="test_main.py" complexity="0" line-rate="1" branch-rate="0">
100
  <methods/>
101
  <lines>
102
  <line number="1" hits="1"/>
103
  <line number="2" hits="1"/>
104
- <line number="3" hits="1"/>
105
  <line number="4" hits="1"/>
106
  <line number="5" hits="1"/>
107
- <line number="6" hits="1"/>
108
  <line number="7" hits="1"/>
109
- <line number="8" hits="1"/>
110
  <line number="9" hits="1"/>
111
- <line number="10" hits="1"/>
112
  <line number="11" hits="1"/>
113
  <line number="12" hits="1"/>
114
  <line number="13" hits="1"/>
115
  <line number="14" hits="1"/>
116
- <line number="15" hits="1"/>
 
 
 
 
 
 
 
 
 
117
  </lines>
118
  </class>
119
  </classes>
120
  </package>
121
- <package name="custom_mmcv" line-rate="0.9828" branch-rate="0" complexity="0">
122
  <classes>
123
- <class name="color.py" filename="custom_mmcv/color.py" complexity="0" line-rate="0.9688" branch-rate="0">
124
  <methods/>
125
  <lines>
126
  <line number="2" hits="1"/>
@@ -137,27 +123,27 @@
137
  <line number="21" hits="1"/>
138
  <line number="22" hits="1"/>
139
  <line number="25" hits="1"/>
140
- <line number="34" hits="1"/>
141
- <line number="35" hits="1"/>
142
- <line number="36" hits="1"/>
143
  <line number="37" hits="0"/>
144
- <line number="38" hits="1"/>
145
- <line number="39" hits="1"/>
146
- <line number="40" hits="1"/>
147
- <line number="41" hits="1"/>
148
- <line number="42" hits="1"/>
149
- <line number="43" hits="1"/>
150
- <line number="44" hits="1"/>
151
- <line number="45" hits="1"/>
152
- <line number="46" hits="1"/>
153
- <line number="47" hits="1"/>
154
- <line number="48" hits="1"/>
155
- <line number="49" hits="1"/>
156
- <line number="50" hits="1"/>
157
- <line number="52" hits="1"/>
158
  </lines>
159
  </class>
160
- <class name="main.py" filename="custom_mmcv/main.py" complexity="0" line-rate="0.9706" branch-rate="0">
161
  <methods/>
162
  <lines>
163
  <line number="4" hits="1"/>
@@ -167,88 +153,33 @@
167
  <line number="10" hits="1"/>
168
  <line number="13" hits="1"/>
169
  <line number="16" hits="1"/>
170
- <line number="50" hits="1"/>
171
- <line number="51" hits="1"/>
172
- <line number="52" hits="1"/>
173
- <line number="53" hits="1"/>
174
- <line number="54" hits="1"/>
175
- <line number="56" hits="1"/>
176
- <line number="57" hits="1"/>
177
- <line number="58" hits="1"/>
178
- <line number="59" hits="1"/>
179
- <line number="60" hits="1"/>
180
- <line number="61" hits="1"/>
181
- <line number="63" hits="1"/>
182
- <line number="64" hits="1"/>
183
- <line number="66" hits="1"/>
184
- <line number="67" hits="1"/>
185
- <line number="68" hits="1"/>
186
- <line number="69" hits="1"/>
187
- <line number="70" hits="1"/>
188
- <line number="71" hits="1"/>
189
- <line number="72" hits="1"/>
190
- <line number="73" hits="1"/>
191
- <line number="74" hits="1"/>
192
- <line number="75" hits="1"/>
193
- <line number="76" hits="1"/>
194
- <line number="86" hits="1"/>
195
  <line number="87" hits="0"/>
196
- <line number="88" hits="1"/>
197
- </lines>
198
- </class>
199
- <class name="test_custom_mmcv.py" filename="custom_mmcv/test_custom_mmcv.py" complexity="0" line-rate="1" branch-rate="0">
200
- <methods/>
201
- <lines>
202
- <line number="1" hits="1"/>
203
- <line number="2" hits="1"/>
204
- <line number="3" hits="1"/>
205
- <line number="4" hits="1"/>
206
- <line number="5" hits="1"/>
207
- <line number="6" hits="1"/>
208
- <line number="7" hits="1"/>
209
- <line number="8" hits="1"/>
210
- <line number="9" hits="1"/>
211
- <line number="10" hits="1"/>
212
- <line number="11" hits="1"/>
213
- <line number="12" hits="1"/>
214
- <line number="13" hits="1"/>
215
- <line number="14" hits="1"/>
216
- <line number="15" hits="1"/>
217
- <line number="16" hits="1"/>
218
- <line number="17" hits="1"/>
219
- <line number="18" hits="1"/>
220
- <line number="19" hits="1"/>
221
- <line number="20" hits="1"/>
222
- <line number="21" hits="1"/>
223
- <line number="22" hits="1"/>
224
- <line number="23" hits="1"/>
225
- <line number="24" hits="1"/>
226
- <line number="25" hits="1"/>
227
- <line number="26" hits="1"/>
228
- <line number="27" hits="1"/>
229
- <line number="28" hits="1"/>
230
- <line number="29" hits="1"/>
231
- <line number="30" hits="1"/>
232
- <line number="31" hits="1"/>
233
- <line number="32" hits="1"/>
234
- <line number="33" hits="1"/>
235
- <line number="34" hits="1"/>
236
- <line number="35" hits="1"/>
237
- <line number="36" hits="1"/>
238
- <line number="37" hits="1"/>
239
- <line number="38" hits="1"/>
240
- <line number="39" hits="1"/>
241
- <line number="40" hits="1"/>
242
- <line number="41" hits="1"/>
243
- <line number="42" hits="1"/>
244
- <line number="43" hits="1"/>
245
- <line number="44" hits="1"/>
246
- <line number="45" hits="1"/>
247
- <line number="46" hits="1"/>
248
- <line number="47" hits="1"/>
249
- <line number="48" hits="1"/>
250
- <line number="49" hits="1"/>
251
- <line number="50" hits="1"/>
252
  </lines>
253
  </class>
254
  </classes>
@@ -273,9 +204,9 @@
273
  </class>
274
  </classes>
275
  </package>
276
- <package name="routers" line-rate="0.7432" branch-rate="0" complexity="0">
277
  <classes>
278
- <class name="friend_request.py" filename="routers/friend_request.py" complexity="0" line-rate="0.6548" branch-rate="0">
279
  <methods/>
280
  <lines>
281
  <line number="1" hits="1"/>
@@ -302,44 +233,44 @@
302
  <line number="35" hits="0"/>
303
  <line number="42" hits="1"/>
304
  <line number="43" hits="1"/>
305
- <line number="44" hits="1"/>
306
  <line number="45" hits="0"/>
307
- <line number="46" hits="1"/>
308
- <line number="55" hits="1"/>
309
- <line number="56" hits="1"/>
310
- <line number="57" hits="1"/>
311
- <line number="58" hits="1"/>
312
- <line number="59" hits="1"/>
313
- <line number="60" hits="1"/>
314
  <line number="61" hits="0"/>
315
  <line number="62" hits="0"/>
316
  <line number="63" hits="0"/>
317
  <line number="64" hits="0"/>
318
  <line number="67" hits="1"/>
319
  <line number="68" hits="1"/>
320
- <line number="69" hits="1"/>
321
  <line number="70" hits="0"/>
322
- <line number="72" hits="1"/>
323
- <line number="73" hits="1"/>
324
- <line number="75" hits="1"/>
325
  <line number="76" hits="0"/>
326
- <line number="78" hits="1"/>
327
- <line number="80" hits="1"/>
328
  <line number="81" hits="0"/>
329
- <line number="83" hits="1"/>
330
  <line number="84" hits="0"/>
331
- <line number="86" hits="1"/>
332
  <line number="87" hits="0"/>
333
  <line number="88" hits="0"/>
334
  <line number="89" hits="0"/>
335
  <line number="90" hits="0"/>
336
  <line number="91" hits="0"/>
337
- <line number="93" hits="1"/>
338
- <line number="94" hits="1"/>
339
- <line number="97" hits="1"/>
340
- <line number="98" hits="1"/>
341
  <line number="101" hits="1"/>
342
- <line number="102" hits="1"/>
343
  <line number="105" hits="1"/>
344
  <line number="106" hits="0"/>
345
  <line number="109" hits="1"/>
@@ -355,16 +286,16 @@
355
  <line number="122" hits="0"/>
356
  <line number="124" hits="0"/>
357
  <line number="127" hits="1"/>
358
- <line number="128" hits="1"/>
359
  <line number="131" hits="1"/>
360
- <line number="132" hits="1"/>
361
  <line number="135" hits="1"/>
362
- <line number="136" hits="1"/>
363
  <line number="139" hits="1"/>
364
- <line number="140" hits="1"/>
365
  </lines>
366
  </class>
367
- <class name="image.py" filename="routers/image.py" complexity="0" line-rate="0.9722" branch-rate="0">
368
  <methods/>
369
  <lines>
370
  <line number="1" hits="1"/>
@@ -378,31 +309,31 @@
378
  <line number="11" hits="1"/>
379
  <line number="14" hits="1"/>
380
  <line number="15" hits="1"/>
381
- <line number="20" hits="1"/>
382
- <line number="21" hits="1"/>
383
- <line number="22" hits="1"/>
384
- <line number="23" hits="1"/>
385
- <line number="24" hits="1"/>
386
- <line number="26" hits="1"/>
387
- <line number="27" hits="1"/>
388
- <line number="28" hits="1"/>
389
- <line number="29" hits="1"/>
390
- <line number="31" hits="1"/>
391
- <line number="33" hits="1"/>
392
  <line number="34" hits="0"/>
393
- <line number="35" hits="1"/>
394
- <line number="37" hits="1"/>
395
  <line number="40" hits="1"/>
396
- <line number="41" hits="1"/>
397
- <line number="42" hits="1"/>
398
- <line number="43" hits="1"/>
399
- <line number="44" hits="1"/>
400
- <line number="45" hits="1"/>
401
- <line number="46" hits="1"/>
402
- <line number="48" hits="1"/>
403
- <line number="49" hits="1"/>
404
- <line number="51" hits="1"/>
405
- <line number="52" hits="1"/>
406
  </lines>
407
  </class>
408
  <class name="me.py" filename="routers/me.py" complexity="0" line-rate="0.7778" branch-rate="0">
@@ -419,114 +350,7 @@
419
  <line number="16" hits="0"/>
420
  </lines>
421
  </class>
422
- <class name="test_friend_request.py" filename="routers/test_friend_request.py" complexity="0" line-rate="0.9608" branch-rate="0">
423
- <methods/>
424
- <lines>
425
- <line number="1" hits="1"/>
426
- <line number="2" hits="1"/>
427
- <line number="3" hits="1"/>
428
- <line number="4" hits="1"/>
429
- <line number="5" hits="1"/>
430
- <line number="6" hits="1"/>
431
- <line number="7" hits="1"/>
432
- <line number="8" hits="1"/>
433
- <line number="9" hits="1"/>
434
- <line number="10" hits="1"/>
435
- <line number="11" hits="1"/>
436
- <line number="12" hits="1"/>
437
- <line number="13" hits="1"/>
438
- <line number="14" hits="1"/>
439
- <line number="15" hits="1"/>
440
- <line number="16" hits="1"/>
441
- <line number="17" hits="1"/>
442
- <line number="18" hits="1"/>
443
- <line number="19" hits="1"/>
444
- <line number="20" hits="1"/>
445
- <line number="21" hits="1"/>
446
- <line number="30" hits="1"/>
447
- <line number="31" hits="1"/>
448
- <line number="32" hits="1"/>
449
- <line number="33" hits="1"/>
450
- <line number="34" hits="1"/>
451
- <line number="35" hits="0"/>
452
- <line number="36" hits="0"/>
453
- <line number="37" hits="1"/>
454
- <line number="38" hits="1"/>
455
- <line number="39" hits="1"/>
456
- <line number="40" hits="1"/>
457
- <line number="41" hits="1"/>
458
- <line number="42" hits="1"/>
459
- <line number="43" hits="1"/>
460
- <line number="45" hits="1"/>
461
- <line number="50" hits="1"/>
462
- <line number="53" hits="1"/>
463
- <line number="54" hits="1"/>
464
- <line number="55" hits="1"/>
465
- <line number="56" hits="1"/>
466
- <line number="57" hits="1"/>
467
- <line number="58" hits="1"/>
468
- <line number="59" hits="1"/>
469
- <line number="60" hits="0"/>
470
- <line number="61" hits="0"/>
471
- <line number="63" hits="1"/>
472
- <line number="66" hits="1"/>
473
- <line number="68" hits="1"/>
474
- <line number="69" hits="1"/>
475
- <line number="70" hits="1"/>
476
- <line number="72" hits="1"/>
477
- <line number="77" hits="1"/>
478
- <line number="80" hits="1"/>
479
- <line number="81" hits="1"/>
480
- <line number="82" hits="1"/>
481
- <line number="83" hits="1"/>
482
- <line number="84" hits="1"/>
483
- <line number="85" hits="1"/>
484
- <line number="86" hits="1"/>
485
- <line number="88" hits="1"/>
486
- <line number="89" hits="1"/>
487
- <line number="91" hits="1"/>
488
- <line number="92" hits="1"/>
489
- <line number="93" hits="1"/>
490
- <line number="94" hits="1"/>
491
- <line number="96" hits="1"/>
492
- <line number="97" hits="1"/>
493
- <line number="99" hits="1"/>
494
- <line number="100" hits="1"/>
495
- <line number="103" hits="1"/>
496
- <line number="104" hits="1"/>
497
- <line number="106" hits="1"/>
498
- <line number="107" hits="1"/>
499
- <line number="111" hits="1"/>
500
- <line number="112" hits="1"/>
501
- <line number="114" hits="1"/>
502
- <line number="115" hits="1"/>
503
- <line number="119" hits="1"/>
504
- <line number="120" hits="1"/>
505
- <line number="122" hits="1"/>
506
- <line number="123" hits="1"/>
507
- <line number="124" hits="1"/>
508
- <line number="128" hits="1"/>
509
- <line number="130" hits="1"/>
510
- <line number="131" hits="1"/>
511
- <line number="133" hits="1"/>
512
- <line number="135" hits="1"/>
513
- <line number="138" hits="1"/>
514
- <line number="140" hits="1"/>
515
- <line number="141" hits="1"/>
516
- <line number="142" hits="1"/>
517
- <line number="146" hits="1"/>
518
- <line number="147" hits="1"/>
519
- <line number="150" hits="1"/>
520
- <line number="152" hits="1"/>
521
- <line number="153" hits="1"/>
522
- <line number="154" hits="1"/>
523
- <line number="158" hits="1"/>
524
- <line number="159" hits="1"/>
525
- <line number="161" hits="1"/>
526
- <line number="162" hits="1"/>
527
- </lines>
528
- </class>
529
- <class name="test_image.py" filename="routers/test_image.py" complexity="0" line-rate="1" branch-rate="0">
530
  <methods/>
531
  <lines>
532
  <line number="1" hits="1"/>
@@ -539,78 +363,17 @@
539
  <line number="8" hits="1"/>
540
  <line number="9" hits="1"/>
541
  <line number="10" hits="1"/>
542
- <line number="11" hits="1"/>
543
- <line number="12" hits="1"/>
544
- <line number="13" hits="1"/>
545
- <line number="14" hits="1"/>
546
- <line number="15" hits="1"/>
547
- <line number="16" hits="1"/>
548
- <line number="17" hits="1"/>
549
  <line number="18" hits="1"/>
550
  <line number="19" hits="1"/>
551
  <line number="20" hits="1"/>
552
  <line number="21" hits="1"/>
553
  <line number="22" hits="1"/>
554
  <line number="23" hits="1"/>
555
- <line number="24" hits="1"/>
556
  <line number="25" hits="1"/>
557
- <line number="26" hits="1"/>
558
- <line number="27" hits="1"/>
559
  <line number="28" hits="1"/>
560
  <line number="29" hits="1"/>
561
- <line number="30" hits="1"/>
562
- <line number="31" hits="1"/>
563
- <line number="34" hits="1"/>
564
- <line number="37" hits="1"/>
565
- <line number="38" hits="1"/>
566
- <line number="39" hits="1"/>
567
- <line number="40" hits="1"/>
568
- <line number="41" hits="1"/>
569
- <line number="42" hits="1"/>
570
- <line number="43" hits="1"/>
571
- <line number="46" hits="1"/>
572
- <line number="49" hits="1"/>
573
- <line number="50" hits="1"/>
574
- <line number="51" hits="1"/>
575
- <line number="52" hits="1"/>
576
- <line number="53" hits="1"/>
577
- <line number="56" hits="1"/>
578
- <line number="59" hits="1"/>
579
- <line number="60" hits="1"/>
580
- <line number="61" hits="1"/>
581
- <line number="63" hits="1"/>
582
- <line number="64" hits="1"/>
583
- <line number="65" hits="1"/>
584
- <line number="68" hits="1"/>
585
- <line number="71" hits="1"/>
586
- <line number="72" hits="1"/>
587
- <line number="73" hits="1"/>
588
- <line number="74" hits="1"/>
589
- </lines>
590
- </class>
591
- <class name="video.py" filename="routers/video.py" complexity="0" line-rate="0.2564" branch-rate="0">
592
- <methods/>
593
- <lines>
594
- <line number="1" hits="1"/>
595
- <line number="2" hits="1"/>
596
- <line number="3" hits="1"/>
597
- <line number="4" hits="1"/>
598
- <line number="5" hits="1"/>
599
- <line number="6" hits="1"/>
600
- <line number="7" hits="1"/>
601
- <line number="8" hits="1"/>
602
- <line number="9" hits="1"/>
603
- <line number="10" hits="1"/>
604
- <line number="18" hits="1"/>
605
- <line number="19" hits="1"/>
606
- <line number="20" hits="1"/>
607
- <line number="21" hits="1"/>
608
- <line number="23" hits="1"/>
609
- <line number="26" hits="1"/>
610
- <line number="27" hits="1"/>
611
- <line number="34" hits="0"/>
612
  <line number="35" hits="0"/>
613
- <line number="40" hits="0"/>
614
  <line number="41" hits="0"/>
615
  <line number="42" hits="0"/>
616
  <line number="43" hits="0"/>
@@ -622,53 +385,69 @@
622
  <line number="49" hits="0"/>
623
  <line number="50" hits="0"/>
624
  <line number="51" hits="0"/>
625
- <line number="54" hits="1"/>
 
 
626
  <line number="55" hits="0"/>
627
  <line number="58" hits="1"/>
628
  <line number="59" hits="0"/>
629
- <line number="60" hits="0"/>
630
- <line number="61" hits="0"/>
631
  <line number="64" hits="0"/>
632
  <line number="65" hits="0"/>
 
633
  <line number="69" hits="0"/>
634
- <line number="76" hits="0"/>
635
- <line number="77" hits="0"/>
636
- <line number="78" hits="0"/>
637
- <line number="79" hits="0"/>
638
  <line number="80" hits="0"/>
639
  <line number="81" hits="0"/>
640
  <line number="82" hits="0"/>
 
641
  <line number="84" hits="0"/>
642
  <line number="85" hits="0"/>
643
- <line number="87" hits="0"/>
644
  <line number="88" hits="0"/>
645
- <line number="90" hits="0"/>
646
  <line number="91" hits="0"/>
647
- <line number="93" hits="0"/>
648
  <line number="94" hits="0"/>
 
649
  <line number="97" hits="0"/>
650
- <line number="99" hits="0"/>
651
  <line number="101" hits="0"/>
652
- <line number="102" hits="0"/>
653
  <line number="103" hits="0"/>
 
 
654
  <line number="107" hits="0"/>
655
- <line number="108" hits="0"/>
656
  <line number="111" hits="0"/>
 
657
  <line number="115" hits="0"/>
658
- <line number="116" hits="0"/>
659
- <line number="117" hits="0"/>
660
- <line number="118" hits="0"/>
661
  <line number="119" hits="0"/>
662
  <line number="120" hits="0"/>
 
663
  <line number="122" hits="0"/>
664
- <line number="134" hits="0"/>
665
- <line number="135" hits="0"/>
666
- <line number="144" hits="0"/>
667
- <line number="147" hits="1"/>
 
668
  <line number="148" hits="0"/>
669
- <line number="149" hits="0"/>
670
- <line number="150" hits="0"/>
671
- <line number="151" hits="0"/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
672
  </lines>
673
  </class>
674
  </classes>
 
1
  <?xml version="1.0" ?>
2
+ <coverage version="7.2.2" timestamp="1699417927975" lines-valid="375" lines-covered="149" line-rate="0.3973" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
3
  <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.2.2 -->
4
  <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
5
  <sources>
6
  <source>D:\SE113.O12_KCPM\app</source>
7
  </sources>
8
  <packages>
9
+ <package name="." line-rate="0.7027" branch-rate="0" complexity="0">
10
  <classes>
11
  <class name="__init__.py" filename="__init__.py" complexity="0" line-rate="0.963" branch-rate="0">
12
  <methods/>
 
48
  <line number="170" hits="1"/>
49
  </lines>
50
  </class>
51
+ <class name="dependencies.py" filename="dependencies.py" complexity="0" line-rate="0.3333" branch-rate="0">
52
  <methods/>
53
  <lines>
54
  <line number="1" hits="1"/>
 
56
  <line number="3" hits="1"/>
57
  <line number="4" hits="1"/>
58
  <line number="5" hits="1"/>
59
+ <line number="6" hits="1"/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  <line number="8" hits="1"/>
 
61
  <line number="11" hits="1"/>
62
+ <line number="14" hits="0"/>
63
+ <line number="15" hits="0"/>
64
+ <line number="16" hits="0"/>
65
+ <line number="17" hits="0"/>
66
  <line number="18" hits="0"/>
67
  <line number="19" hits="0"/>
68
+ <line number="20" hits="0"/>
 
 
69
  <line number="25" hits="0"/>
70
+ <line number="26" hits="0"/>
71
+ <line number="31" hits="0"/>
72
+ <line number="32" hits="0"/>
73
+ <line number="38" hits="0"/>
74
+ <line number="39" hits="0"/>
75
+ <line number="40" hits="0"/>
76
+ <line number="41" hits="0"/>
77
+ <line number="43" hits="0"/>
78
  </lines>
79
  </class>
80
+ <class name="main.py" filename="main.py" complexity="0" line-rate="0.75" branch-rate="0">
81
  <methods/>
82
  <lines>
83
  <line number="1" hits="1"/>
84
  <line number="2" hits="1"/>
 
85
  <line number="4" hits="1"/>
86
  <line number="5" hits="1"/>
 
87
  <line number="7" hits="1"/>
 
88
  <line number="9" hits="1"/>
 
89
  <line number="11" hits="1"/>
90
  <line number="12" hits="1"/>
91
  <line number="13" hits="1"/>
92
  <line number="14" hits="1"/>
93
+ <line number="17" hits="1"/>
94
+ <line number="18" hits="1"/>
95
+ <line number="19" hits="0"/>
96
+ <line number="20" hits="0"/>
97
+ <line number="23" hits="1"/>
98
+ <line number="24" hits="1"/>
99
+ <line number="25" hits="0"/>
100
+ <line number="26" hits="0"/>
101
+ <line number="29" hits="1"/>
102
+ <line number="30" hits="0"/>
103
  </lines>
104
  </class>
105
  </classes>
106
  </package>
107
+ <package name="custom_mmcv" line-rate="0.3182" branch-rate="0" complexity="0">
108
  <classes>
109
+ <class name="color.py" filename="custom_mmcv/color.py" complexity="0" line-rate="0.4375" branch-rate="0">
110
  <methods/>
111
  <lines>
112
  <line number="2" hits="1"/>
 
123
  <line number="21" hits="1"/>
124
  <line number="22" hits="1"/>
125
  <line number="25" hits="1"/>
126
+ <line number="34" hits="0"/>
127
+ <line number="35" hits="0"/>
128
+ <line number="36" hits="0"/>
129
  <line number="37" hits="0"/>
130
+ <line number="38" hits="0"/>
131
+ <line number="39" hits="0"/>
132
+ <line number="40" hits="0"/>
133
+ <line number="41" hits="0"/>
134
+ <line number="42" hits="0"/>
135
+ <line number="43" hits="0"/>
136
+ <line number="44" hits="0"/>
137
+ <line number="45" hits="0"/>
138
+ <line number="46" hits="0"/>
139
+ <line number="47" hits="0"/>
140
+ <line number="48" hits="0"/>
141
+ <line number="49" hits="0"/>
142
+ <line number="50" hits="0"/>
143
+ <line number="52" hits="0"/>
144
  </lines>
145
  </class>
146
+ <class name="main.py" filename="custom_mmcv/main.py" complexity="0" line-rate="0.2059" branch-rate="0">
147
  <methods/>
148
  <lines>
149
  <line number="4" hits="1"/>
 
153
  <line number="10" hits="1"/>
154
  <line number="13" hits="1"/>
155
  <line number="16" hits="1"/>
156
+ <line number="50" hits="0"/>
157
+ <line number="51" hits="0"/>
158
+ <line number="52" hits="0"/>
159
+ <line number="53" hits="0"/>
160
+ <line number="54" hits="0"/>
161
+ <line number="56" hits="0"/>
162
+ <line number="57" hits="0"/>
163
+ <line number="58" hits="0"/>
164
+ <line number="59" hits="0"/>
165
+ <line number="60" hits="0"/>
166
+ <line number="61" hits="0"/>
167
+ <line number="63" hits="0"/>
168
+ <line number="64" hits="0"/>
169
+ <line number="66" hits="0"/>
170
+ <line number="67" hits="0"/>
171
+ <line number="68" hits="0"/>
172
+ <line number="69" hits="0"/>
173
+ <line number="70" hits="0"/>
174
+ <line number="71" hits="0"/>
175
+ <line number="72" hits="0"/>
176
+ <line number="73" hits="0"/>
177
+ <line number="74" hits="0"/>
178
+ <line number="75" hits="0"/>
179
+ <line number="76" hits="0"/>
180
+ <line number="86" hits="0"/>
181
  <line number="87" hits="0"/>
182
+ <line number="88" hits="0"/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  </lines>
184
  </class>
185
  </classes>
 
204
  </class>
205
  </classes>
206
  </package>
207
+ <package name="routers" line-rate="0.3214" branch-rate="0" complexity="0">
208
  <classes>
209
+ <class name="friend_request.py" filename="routers/friend_request.py" complexity="0" line-rate="0.3571" branch-rate="0">
210
  <methods/>
211
  <lines>
212
  <line number="1" hits="1"/>
 
233
  <line number="35" hits="0"/>
234
  <line number="42" hits="1"/>
235
  <line number="43" hits="1"/>
236
+ <line number="44" hits="0"/>
237
  <line number="45" hits="0"/>
238
+ <line number="46" hits="0"/>
239
+ <line number="55" hits="0"/>
240
+ <line number="56" hits="0"/>
241
+ <line number="57" hits="0"/>
242
+ <line number="58" hits="0"/>
243
+ <line number="59" hits="0"/>
244
+ <line number="60" hits="0"/>
245
  <line number="61" hits="0"/>
246
  <line number="62" hits="0"/>
247
  <line number="63" hits="0"/>
248
  <line number="64" hits="0"/>
249
  <line number="67" hits="1"/>
250
  <line number="68" hits="1"/>
251
+ <line number="69" hits="0"/>
252
  <line number="70" hits="0"/>
253
+ <line number="72" hits="0"/>
254
+ <line number="73" hits="0"/>
255
+ <line number="75" hits="0"/>
256
  <line number="76" hits="0"/>
257
+ <line number="78" hits="0"/>
258
+ <line number="80" hits="0"/>
259
  <line number="81" hits="0"/>
260
+ <line number="83" hits="0"/>
261
  <line number="84" hits="0"/>
262
+ <line number="86" hits="0"/>
263
  <line number="87" hits="0"/>
264
  <line number="88" hits="0"/>
265
  <line number="89" hits="0"/>
266
  <line number="90" hits="0"/>
267
  <line number="91" hits="0"/>
268
+ <line number="93" hits="0"/>
269
+ <line number="94" hits="0"/>
270
+ <line number="97" hits="0"/>
271
+ <line number="98" hits="0"/>
272
  <line number="101" hits="1"/>
273
+ <line number="102" hits="0"/>
274
  <line number="105" hits="1"/>
275
  <line number="106" hits="0"/>
276
  <line number="109" hits="1"/>
 
286
  <line number="122" hits="0"/>
287
  <line number="124" hits="0"/>
288
  <line number="127" hits="1"/>
289
+ <line number="128" hits="0"/>
290
  <line number="131" hits="1"/>
291
+ <line number="132" hits="0"/>
292
  <line number="135" hits="1"/>
293
+ <line number="136" hits="0"/>
294
  <line number="139" hits="1"/>
295
+ <line number="140" hits="0"/>
296
  </lines>
297
  </class>
298
+ <class name="image.py" filename="routers/image.py" complexity="0" line-rate="0.3333" branch-rate="0">
299
  <methods/>
300
  <lines>
301
  <line number="1" hits="1"/>
 
309
  <line number="11" hits="1"/>
310
  <line number="14" hits="1"/>
311
  <line number="15" hits="1"/>
312
+ <line number="20" hits="0"/>
313
+ <line number="21" hits="0"/>
314
+ <line number="22" hits="0"/>
315
+ <line number="23" hits="0"/>
316
+ <line number="24" hits="0"/>
317
+ <line number="26" hits="0"/>
318
+ <line number="27" hits="0"/>
319
+ <line number="28" hits="0"/>
320
+ <line number="29" hits="0"/>
321
+ <line number="31" hits="0"/>
322
+ <line number="33" hits="0"/>
323
  <line number="34" hits="0"/>
324
+ <line number="35" hits="0"/>
325
+ <line number="37" hits="0"/>
326
  <line number="40" hits="1"/>
327
+ <line number="41" hits="0"/>
328
+ <line number="42" hits="0"/>
329
+ <line number="43" hits="0"/>
330
+ <line number="44" hits="0"/>
331
+ <line number="45" hits="0"/>
332
+ <line number="46" hits="0"/>
333
+ <line number="48" hits="0"/>
334
+ <line number="49" hits="0"/>
335
+ <line number="51" hits="0"/>
336
+ <line number="52" hits="0"/>
337
  </lines>
338
  </class>
339
  <class name="me.py" filename="routers/me.py" complexity="0" line-rate="0.7778" branch-rate="0">
 
350
  <line number="16" hits="0"/>
351
  </lines>
352
  </class>
353
+ <class name="video.py" filename="routers/video.py" complexity="0" line-rate="0.2421" branch-rate="0">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  <methods/>
355
  <lines>
356
  <line number="1" hits="1"/>
 
363
  <line number="8" hits="1"/>
364
  <line number="9" hits="1"/>
365
  <line number="10" hits="1"/>
 
 
 
 
 
 
 
366
  <line number="18" hits="1"/>
367
  <line number="19" hits="1"/>
368
  <line number="20" hits="1"/>
369
  <line number="21" hits="1"/>
370
  <line number="22" hits="1"/>
371
  <line number="23" hits="1"/>
 
372
  <line number="25" hits="1"/>
 
 
373
  <line number="28" hits="1"/>
374
  <line number="29" hits="1"/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  <line number="35" hits="0"/>
376
+ <line number="36" hits="0"/>
377
  <line number="41" hits="0"/>
378
  <line number="42" hits="0"/>
379
  <line number="43" hits="0"/>
 
385
  <line number="49" hits="0"/>
386
  <line number="50" hits="0"/>
387
  <line number="51" hits="0"/>
388
+ <line number="52" hits="0"/>
389
+ <line number="53" hits="0"/>
390
+ <line number="54" hits="0"/>
391
  <line number="55" hits="0"/>
392
  <line number="58" hits="1"/>
393
  <line number="59" hits="0"/>
394
+ <line number="62" hits="1"/>
395
+ <line number="63" hits="0"/>
396
  <line number="64" hits="0"/>
397
  <line number="65" hits="0"/>
398
+ <line number="68" hits="0"/>
399
  <line number="69" hits="0"/>
400
+ <line number="73" hits="0"/>
 
 
 
401
  <line number="80" hits="0"/>
402
  <line number="81" hits="0"/>
403
  <line number="82" hits="0"/>
404
+ <line number="83" hits="0"/>
405
  <line number="84" hits="0"/>
406
  <line number="85" hits="0"/>
407
+ <line number="86" hits="0"/>
408
  <line number="88" hits="0"/>
409
+ <line number="89" hits="0"/>
410
  <line number="91" hits="0"/>
411
+ <line number="92" hits="0"/>
412
  <line number="94" hits="0"/>
413
+ <line number="95" hits="0"/>
414
  <line number="97" hits="0"/>
415
+ <line number="98" hits="0"/>
416
  <line number="101" hits="0"/>
 
417
  <line number="103" hits="0"/>
418
+ <line number="105" hits="0"/>
419
+ <line number="106" hits="0"/>
420
  <line number="107" hits="0"/>
 
421
  <line number="111" hits="0"/>
422
+ <line number="112" hits="0"/>
423
  <line number="115" hits="0"/>
 
 
 
424
  <line number="119" hits="0"/>
425
  <line number="120" hits="0"/>
426
+ <line number="121" hits="0"/>
427
  <line number="122" hits="0"/>
428
+ <line number="123" hits="0"/>
429
+ <line number="124" hits="0"/>
430
+ <line number="126" hits="0"/>
431
+ <line number="138" hits="0"/>
432
+ <line number="139" hits="0"/>
433
  <line number="148" hits="0"/>
434
+ <line number="151" hits="1"/>
435
+ <line number="152" hits="0"/>
436
+ <line number="153" hits="0"/>
437
+ <line number="154" hits="0"/>
438
+ <line number="157" hits="1"/>
439
+ <line number="158" hits="0"/>
440
+ <line number="159" hits="0"/>
441
+ <line number="160" hits="0"/>
442
+ <line number="161" hits="0"/>
443
+ <line number="162" hits="0"/>
444
+ <line number="163" hits="0"/>
445
+ <line number="164" hits="0"/>
446
+ <line number="165" hits="0"/>
447
+ <line number="166" hits="0"/>
448
+ <line number="178" hits="0"/>
449
+ <line number="189" hits="0"/>
450
+ <line number="190" hits="0"/>
451
  </lines>
452
  </class>
453
  </classes>
tests/test_friend_request.py CHANGED
@@ -3,13 +3,13 @@ import pytest
3
  import json
4
  import cv2
5
  import mmcv
6
- import firebase_admin
7
  import requests
8
  from fastapi.testclient import TestClient
9
  from app.main import app
10
  from app import db
11
  from app.constants import deviceId
12
  from fastapi.routing import APIRoute
 
13
  from google.cloud.firestore_v1.base_query import FieldFilter
14
  def endpoints():
15
  endpoints = []
@@ -148,4 +148,4 @@ class TestFriendRequest():
148
  # Delete entity for next time test
149
  user_ref.document(inviter['id']).delete()
150
  user_ref.document(invitee['id']).delete()
151
-
 
3
  import json
4
  import cv2
5
  import mmcv
 
6
  import requests
7
  from fastapi.testclient import TestClient
8
  from app.main import app
9
  from app import db
10
  from app.constants import deviceId
11
  from fastapi.routing import APIRoute
12
+ from app import db
13
  from google.cloud.firestore_v1.base_query import FieldFilter
14
  def endpoints():
15
  endpoints = []
 
148
  # Delete entity for next time test
149
  user_ref.document(inviter['id']).delete()
150
  user_ref.document(invitee['id']).delete()
151
+
tests/test_video.py CHANGED
@@ -1,6 +1,8 @@
1
  from fastapi.testclient import TestClient
2
  from fastapi.routing import APIRoute
 
3
  from app.main import app
 
4
  from app import db
5
  import os
6
  import pytest
@@ -21,8 +23,9 @@ def client():
21
  @pytest.fixture
22
  def user():
23
  url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + os.environ.get("FIREBASE_API_KEY")
 
24
  payload = json.dumps({
25
- "email": "test@gmail.com",
26
  "password": "testing",
27
  "returnSecureToken": True
28
  })
@@ -33,31 +36,55 @@ def user():
33
  data = response.json()
34
  user = {"id": data['localId'], "token": data["idToken"]}
35
  yield user
 
36
  class TestVideoAPI:
37
  @pytest.mark.skipif("/video" not in endpoints(),reason="Route not defined")
38
  def test_video_API(self, user, client):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # Test when sent file is not a video
 
40
  payload = {}
41
  files=[
42
  ('file',('demo.jpg',open('demo.jpg','rb'),'application/octet-stream'))
43
  ]
44
  headers = {
45
  'Content-Type': 'application/json',
 
46
  }
47
  response = client.request("POST", 'video', headers=headers, data=payload, files=files)
48
  assert response.status_code == 400
49
  assert response.text == "File must be video"
50
- # Test when no token is pass to route
51
  payload = {}
52
  files=[
53
  ('file',('demo.mp4',open('demo.mp4','rb'),'application/octet-stream'))
54
  ]
55
  headers = {
56
  'Content-Type': 'application/json',
 
57
  }
58
  response = client.request("POST", 'video', headers=headers, data=payload, files=files)
59
  assert response.status_code == 400
60
- assert response.text == "User not found"
61
  # Test when all requirements have been fulfilled
62
  payload = {}
63
  files=[
@@ -79,10 +106,23 @@ class TestVideoAPI:
79
  assert data['name'] == artifactName
80
  assert data['status'] == 'pending'
81
  assert index == 1
82
-
83
-
84
-
85
-
86
-
87
-
 
 
 
 
 
 
 
 
 
 
 
 
88
 
 
 
1
  from fastapi.testclient import TestClient
2
  from fastapi.routing import APIRoute
3
+ from app.routers.video import updateArtifact
4
  from app.main import app
5
+ from app.constants import deviceId
6
  from app import db
7
  import os
8
  import pytest
 
23
  @pytest.fixture
24
  def user():
25
  url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + os.environ.get("FIREBASE_API_KEY")
26
+
27
  payload = json.dumps({
28
+ "email": "test_video@gmail.com",
29
  "password": "testing",
30
  "returnSecureToken": True
31
  })
 
36
  data = response.json()
37
  user = {"id": data['localId'], "token": data["idToken"]}
38
  yield user
39
+ db.collection("user").document(user['id']).delete()
40
  class TestVideoAPI:
41
  @pytest.mark.skipif("/video" not in endpoints(),reason="Route not defined")
42
  def test_video_API(self, user, client):
43
+ # Test when no token is pass to route
44
+ payload = {}
45
+ files=[
46
+ ('file',('demo.mp4',open('demo.mp4','rb'),'application/octet-stream'))
47
+ ]
48
+ headers = {
49
+ 'Content-Type': 'application/json',
50
+ }
51
+ response = client.request("POST", 'video', headers=headers, data=payload, files=files)
52
+ assert response.status_code == 403
53
+ # Test when a dummy (not valid) token passed
54
+ payload = {}
55
+ files=[
56
+ ('file',('demo.mp4',open('demo.mp4','rb'),'application/octet-stream'))
57
+ ]
58
+ headers = {
59
+ 'Content-Type': 'application/json',
60
+ 'Authorization': "Bearer saikoljncaskljnfckjnasckjna"
61
+ }
62
+ response = client.request("POST", 'video', headers=headers, data=payload, files=files)
63
+ assert response.status_code == 401
64
  # Test when sent file is not a video
65
+ db.collection("user").document(user['id']).set({"deviceId": deviceId})
66
  payload = {}
67
  files=[
68
  ('file',('demo.jpg',open('demo.jpg','rb'),'application/octet-stream'))
69
  ]
70
  headers = {
71
  'Content-Type': 'application/json',
72
+ 'Authorization': "Bearer " + user['token']
73
  }
74
  response = client.request("POST", 'video', headers=headers, data=payload, files=files)
75
  assert response.status_code == 400
76
  assert response.text == "File must be video"
77
+ # Test on valid token + user
78
  payload = {}
79
  files=[
80
  ('file',('demo.mp4',open('demo.mp4','rb'),'application/octet-stream'))
81
  ]
82
  headers = {
83
  'Content-Type': 'application/json',
84
+ 'Authorization': "Bearer " + user['id']
85
  }
86
  response = client.request("POST", 'video', headers=headers, data=payload, files=files)
87
  assert response.status_code == 400
 
88
  # Test when all requirements have been fulfilled
89
  payload = {}
90
  files=[
 
106
  assert data['name'] == artifactName
107
  assert data['status'] == 'pending'
108
  assert index == 1
109
+ db.collection("user").document(user['id']).delete()
110
+ def test_update_artifact(self):
111
+ # Check and preprocess test data before testing
112
+ test_artifact = db.collection("artifacts").document('test')
113
+ if not test_artifact.get().exists:
114
+ db.collection("artifacts").add({"name": "test", "path": "", "status": "testing", "thumbnailURL":""})
115
+ test_artifact = db.collection("artifacts").document('test').get()
116
+ else:
117
+ test_artifact.update({"status": "testing", 'path': '', "thumbnailURL":""})
118
+ # Testing update on each field
119
+ updateArtifact(test_artifact['id'], {{"status": "test_done"}})
120
+ assert test_artifact.get().to_dict()['status'] == 'test_done'
121
+ updateArtifact(test_artifact['id'], {{"path": "test_path"}})
122
+ assert test_artifact.get().to_dict()['path'] == 'test_path'
123
+ updateArtifact(test_artifact['id'], {{"thumbnailURL": "test_path"}})
124
+ assert test_artifact.get().to_dict()['thumbnailURl'] == 'test_path'
125
+ #Delete data for next time test
126
+ test_artifact.delete()
127
 
128
+