1+ import pytest
2+ from datetime import datetime , timedelta
3+ from unittest .mock import patch
4+ from rest_framework .exceptions import NotFound
5+
6+ from upload .tokenless .azure import TokenlessAzureHandler
7+
8+ @pytest .fixture
9+ def upload_params ():
10+ return {
11+ "job" : "899861" ,
12+ "project" : "public" ,
13+ "server_uri" : "https://dev.azure.com/dnceng-public/" ,
14+ "build" : "20241219.14" ,
15+ "commit" : "0f6e31fec5876be932f9e52f739ce1a2e04f11e3"
16+ }
17+
18+ def test_verify_handles_nanosecond_timestamp (upload_params ):
19+ """
20+ Test that the handler correctly processes timestamps with nanosecond precision
21+ from the Azure DevOps API.
22+ """
23+ handler = TokenlessAzureHandler (upload_params )
24+
25+ # Mock a response with nanosecond precision timestamp (7 digits after decimal)
26+ current_time = datetime .now ()
27+ timestamp = current_time .strftime ("%Y-%m-%dT%H:%M:%S.1234567Z" )
28+
29+ mock_build_response = {
30+ "status" : "completed" ,
31+ "finishTime" : timestamp ,
32+ "buildNumber" : "20241219.14" ,
33+ "sourceVersion" : "0f6e31fec5876be932f9e52f739ce1a2e04f11e3" ,
34+ "repository" : {"type" : "GitHub" }
35+ }
36+
37+ with patch .object (handler , 'get_build' , return_value = mock_build_response ):
38+ service = handler .verify ()
39+ assert service == "github"
40+
41+ def test_verify_handles_microsecond_timestamp (upload_params ):
42+ """
43+ Test that the handler still works correctly with regular microsecond precision
44+ timestamps.
45+ """
46+ handler = TokenlessAzureHandler (upload_params )
47+
48+ # Mock a response with microsecond precision (6 digits after decimal)
49+ current_time = datetime .now ()
50+ timestamp = current_time .strftime ("%Y-%m-%dT%H:%M:%S.123456Z" )
51+
52+ mock_build_response = {
53+ "status" : "completed" ,
54+ "finishTime" : timestamp ,
55+ "buildNumber" : "20241219.14" ,
56+ "sourceVersion" : "0f6e31fec5876be932f9e52f739ce1a2e04f11e3" ,
57+ "repository" : {"type" : "GitHub" }
58+ }
59+
60+ with patch .object (handler , 'get_build' , return_value = mock_build_response ):
61+ service = handler .verify ()
62+ assert service == "github"
63+
64+ def test_verify_rejects_old_timestamp (upload_params ):
65+ """
66+ Test that the handler correctly rejects timestamps older than 4 minutes,
67+ even with nanosecond precision.
68+ """
69+ handler = TokenlessAzureHandler (upload_params )
70+
71+ # Create a timestamp that's more than 4 minutes old
72+ old_time = datetime .now () - timedelta (minutes = 5 )
73+ timestamp = old_time .strftime ("%Y-%m-%dT%H:%M:%S.1234567Z" )
74+
75+ mock_build_response = {
76+ "status" : "completed" ,
77+ "finishTime" : timestamp ,
78+ "buildNumber" : "20241219.14" ,
79+ "sourceVersion" : "0f6e31fec5876be932f9e52f739ce1a2e04f11e3" ,
80+ "repository" : {"type" : "GitHub" }
81+ }
82+
83+ with patch .object (handler , 'get_build' , return_value = mock_build_response ):
84+ with pytest .raises (NotFound , match = "Azure build has already finished" ):
85+ handler .verify ()
0 commit comments