@@ -3,6 +3,11 @@ use std::sync::atomic::{AtomicU8, Ordering};
33use crate :: integration:: test_utils:: AssertCommand ;
44use crate :: integration:: { MockEndpointBuilder , TestManager } ;
55
6+ /// A test org auth token with org="wat-org" and empty URL.
7+ /// Format: sntrys_{base64_payload}_{base64_secret}
8+ /// Payload: {"iat":1704374159.069583,"url":"","region_url":"","org":"wat-org"}
9+ const ORG_AUTH_TOKEN_WAT_ORG : & str = "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" ;
10+
611#[ test]
712fn command_upload_dart_symbol_map_missing_capability ( ) {
813 // Server does not advertise `dartsymbolmap` capability → command should bail early.
@@ -102,3 +107,79 @@ fn command_upload_dart_symbol_map_invalid_mapping() {
102107 . with_default_token ( )
103108 . run_and_assert ( AssertCommand :: Failure ) ;
104109}
110+
111+ #[ test]
112+ fn command_upload_dart_symbol_map_org_from_token ( ) {
113+ // When no --org is provided and SENTRY_ORG is not set, the org should be resolved
114+ // from the org auth token. This test verifies the fix for CLI-260.
115+ //
116+ // The test uses an org auth token with org="wat-org" (matching mock server paths).
117+ // By unsetting SENTRY_ORG and not providing --org, we verify the org is extracted
118+ // from the token.
119+ let call_count = AtomicU8 :: new ( 0 ) ;
120+
121+ TestManager :: new ( )
122+ // Server advertises capability including `dartsymbolmap`.
123+ // This endpoint uses "wat-org" in the path - if org resolution fails,
124+ // the request would go to a different path and not match.
125+ . mock_endpoint (
126+ MockEndpointBuilder :: new ( "GET" , "/api/0/organizations/wat-org/chunk-upload/" )
127+ . with_response_file ( "dart_symbol_map/get-chunk-upload.json" ) ,
128+ )
129+ // Accept chunk upload requests for the missing chunks
130+ . mock_endpoint ( MockEndpointBuilder :: new (
131+ "POST" ,
132+ "/api/0/organizations/wat-org/chunk-upload/" ,
133+ ) )
134+ // Assemble flow: 1) not_found (missingChunks), 2) created, 3) ok
135+ . mock_endpoint (
136+ MockEndpointBuilder :: new (
137+ "POST" ,
138+ "/api/0/projects/wat-org/wat-project/files/difs/assemble/" ,
139+ )
140+ . with_header_matcher ( "content-type" , "application/json" )
141+ . with_response_fn ( move |request| {
142+ let body = request. body ( ) . expect ( "body should be readable" ) ;
143+ let body_json: serde_json:: Value =
144+ serde_json:: from_slice ( body) . expect ( "request body should be valid JSON" ) ;
145+
146+ let ( checksum, _obj) = body_json
147+ . as_object ( )
148+ . and_then ( |m| m. iter ( ) . next ( ) )
149+ . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
150+ . expect ( "assemble request must contain at least one object" ) ;
151+
152+ match call_count. fetch_add ( 1 , Ordering :: Relaxed ) {
153+ 0 => format ! (
154+ "{{\" {checksum}\" :{{\" state\" :\" not_found\" ,\" missingChunks\" :[\" {checksum}\" ]}}}}"
155+ )
156+ . into ( ) ,
157+ 1 => format ! (
158+ "{{\" {checksum}\" :{{\" state\" :\" created\" ,\" missingChunks\" :[]}}}}"
159+ )
160+ . into ( ) ,
161+ 2 => format ! (
162+ "{{\" {checksum}\" :{{\" state\" :\" ok\" ,\" detail\" :null,\" missingChunks\" :[],\" dif\" :{{\" id\" :\" 1\" ,\" uuid\" :\" 00000000-0000-0000-0000-000000000000\" ,\" debugId\" :\" 00000000-0000-0000-0000-000000000000\" ,\" objectName\" :\" dartsymbolmap.json\" ,\" cpuName\" :\" any\" ,\" headers\" :{{\" Content-Type\" :\" application/octet-stream\" }},\" size\" :1,\" sha1\" :\" {checksum}\" ,\" dateCreated\" :\" 1776-07-04T12:00:00.000Z\" ,\" data\" :{{}}}}}}}}"
163+ )
164+ . into ( ) ,
165+ n => panic ! (
166+ "Only 3 calls to the assemble endpoint expected, but there were {}." ,
167+ n + 1
168+ ) ,
169+ }
170+ } )
171+ . expect ( 3 ) ,
172+ )
173+ . assert_cmd ( [
174+ "dart-symbol-map" ,
175+ "upload" ,
176+ // No --org flag provided!
177+ "tests/integration/_fixtures/dart_symbol_map/dartsymbolmap.json" ,
178+ "tests/integration/_fixtures/Sentry.Samples.Console.Basic.pdb" ,
179+ ] )
180+ // Use org auth token with embedded org="wat-org" instead of default token
181+ . env ( "SENTRY_AUTH_TOKEN" , ORG_AUTH_TOKEN_WAT_ORG )
182+ // Explicitly unset SENTRY_ORG to ensure org comes from token
183+ . env ( "SENTRY_ORG" , "" )
184+ . run_and_assert ( AssertCommand :: Success ) ;
185+ }
0 commit comments