From 75e24aac8c6e86190efa07b01dec9bba16fae4c4 Mon Sep 17 00:00:00 2001 From: ofritz Date: Wed, 21 Jan 2026 16:38:47 +0100 Subject: [PATCH 1/2] feat(conflation): add integration test assets --- ...rojectE2E.test_conflation_project_e2e.yaml | 179 ++++++++ tests/projects/conflation/cover_image.jpg | Bin 0 -> 34830 bytes ...ted_project_aggregated_result_modified.csv | 5 + ...ated_result_with_geometry_modified.geojson | 1 + .../expected_project_groups_modified.csv | 2 + .../exports/expected_project_history.csv | 2 + .../expected_project_result_modified.csv | 5 + .../expected_project_tasks_modified.csv | 5 + .../exports/expected_project_users.csv | 2 + tests/projects/conflation/features.geojson | 1 + tests/projects/conflation/project_data.json5 | 385 ++++++++++++++++++ 11 files changed, 587 insertions(+) create mode 100644 tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml create mode 100644 tests/projects/conflation/cover_image.jpg create mode 100644 tests/projects/conflation/exports/expected_project_aggregated_result_modified.csv create mode 100644 tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson create mode 100644 tests/projects/conflation/exports/expected_project_groups_modified.csv create mode 100644 tests/projects/conflation/exports/expected_project_history.csv create mode 100644 tests/projects/conflation/exports/expected_project_result_modified.csv create mode 100644 tests/projects/conflation/exports/expected_project_tasks_modified.csv create mode 100644 tests/projects/conflation/exports/expected_project_users.csv create mode 100644 tests/projects/conflation/features.geojson create mode 100644 tests/projects/conflation/project_data.json5 diff --git a/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml b/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml new file mode 100644 index 0000000..f07784f --- /dev/null +++ b/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml @@ -0,0 +1,179 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.5 + method: GET + uri: https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f + response: + body: + string: '' + headers: + Accept-CH: + - Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, + Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factors, Sec-CH-UA-Platform, + Sec-CH-UA-Platform-Version + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Content-Length: + - '0' + Content-Security-Policy: + - script-src 'nonce-7pwRZRdV3luL9vhndcbIWQ' 'unsafe-inline';object-src 'none';base-uri + 'self';report-uri /_/DriveUntrustedContentHttp/cspreport;worker-src 'self' + - require-trusted-types-for 'script';report-uri /_/DriveUntrustedContentHttp/cspreport + Content-Type: + - application/binary + Cross-Origin-Opener-Policy: + - same-origin + Date: + - Wed, 21 Jan 2026 15:36:50 GMT + Expires: + - Mon, 01 Jan 1990 00:00:00 GMT + Location: + - https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download + Permissions-Policy: + - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*, + ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factors=*, ch-ua-platform=*, ch-ua-platform-version=* + Pragma: + - no-cache + Server: + - ESF + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - '0' + status: + code: 303 + message: See Other +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.5 + method: GET + uri: https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download + response: + body: + string: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09607039754393,19.42606297126916],[-99.09607039754393,19.42583707815382],[-99.09587079004991,19.42583707815382],[-99.09587079004991,19.42606297126916],[-99.09607039754393,19.42606297126916]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.096234519261,19.42567393293139],[-99.096234519261,19.42543967283784],[-99.09605709037753,19.42543967283784],[-99.09605709037753,19.42567393293139],[-99.096234519261,19.42567393293139]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09455578224427,19.42536198674972],[-99.09455578224427,19.42495865737405],[-99.09425641045227,19.42495865737405],[-99.09425641045227,19.42536198674972],[-99.09455578224427,19.42536198674972]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09346758953988,19.42222047258528],[-99.09346758953988,19.422018804123567],[-99.09335354314331,19.422018804123567],[-99.09335354314331,19.42222047258528],[-99.09346758953988,19.42222047258528]]],"type":"Polygon"}}]}' + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Credentials: + - 'false' + Access-Control-Allow-Headers: + - Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, + Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, + Content-Type, Date, developer-token, financial-institution-id, X-Goog-Sn-Metadata, + X-Goog-Sn-PatientId, GData-Version, google-cloud-resource-prefix, linked-customer-id, + login-customer-id, x-goog-request-params, Host, If-Match, If-Modified-Since, + If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, request-id, + Signature, Signature-Agent, Signature-Input, Slug, Transfer-Encoding, User-Agent, + hotrod-board-name, hotrod-chrome-cpu-model, hotrod-chrome-processors, Want-Digest, + X-Ad-Manager-Impersonation, x-chrome-connected, X-ClientDetails, X-Client-Pctx, + X-Client-Version, x-debug-settings-metadata, X-Firebase-AppId, X-Firebase-AppVersion, + X-Firebase-Locale, X-Goog-Firebase-Installations-Auth, X-Firebase-Client, + X-Firebase-Client-Log-Type, X-Firebase-GMPID, X-Firebase-Auth-Token, X-Firebase-AppCheck, + X-Firebase-RC-Fetch-Type, X-Firebase-Token, X-Goog-Drive-Client-Version, X-Goog-Drive-Resource-Keys, + X-GData-Client, X-GData-Key, X-GoogApps-Allowed-Domains, X-Goog-AdX-Buyer-Impersonation, + X-Goog-Api-Client, X-Goog-Visibilities, X-Goog-AuthUser, X-Google-EOM, x-goog-ext-124712974-jspb, + x-goog-ext-467253834-jspb, x-goog-ext-353267353-bin, x-goog-ext-353267353-jspb, + x-goog-ext-251363160-jspb, x-goog-ext-259736195-jspb, x-goog-ext-477772811-jspb, + x-goog-ext-359275022-bin, x-goog-ext-328800237-jspb, x-goog-ext-198889211-bin, + x-goog-ext-202735639-bin, x-goog-ext-223261916-bin, x-goog-ext-223435598-bin, + x-goog-ext-233818517-bin, x-goog-ext-202964622-bin, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, + X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Request-Reason, X-Goog-Request-Time, + X-Goog-Experiments, x-goog-iam-authority-selector, x-goog-iam-authorization-token, + X-Goog-Spatula, X-Goog-Travel-Bgr, X-Goog-Travel-Settings, X-Goog-Upload-Command, + X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, + X-Goog-Upload-File-Name, X-Goog-Upload-Header-Content-Encoding, X-Goog-Upload-Header-Content-Length, + X-Goog-Upload-Header-Content-Type, X-Goog-Upload-Header-Transfer-Encoding, + X-Goog-Upload-Offset, X-Goog-Upload-Protocol, x-goog-user-project, X-Goog-Visitor-Id, + X-Goog-FieldMask, X-Google-Project-Override, x-goog-maps-api-salt, x-goog-maps-api-signature, + x-goog-maps-client-id, X-Goog-Api-Key, x-goog-spanner-database-role, X-HTTP-Method-Override, + X-JavaScript-User-Agent, X-Pan-Versionid, X-Proxied-User-IP, X-Origin, X-Referer, + X-Requested-With, X-Stadia-Client-Context, X-Upload-Content-Length, X-Upload-Content-Type, + X-Use-Alt-Service, X-Use-HTTP-Status-Code-Override, X-Ios-Bundle-Identifier, + X-Places-Ios-Sdk, X-Android-Package, X-Android-Cert, X-Places-Android-Sdk, + X-Goog-Maps-Ios-Uuid, X-Goog-Maps-Android-Uuid, X-Ariane-Xsrf-Token, X-YouTube-Bootstrap-Logged-In, + X-Youtube-Client-Name, X-Youtube-Client-Version, X-Youtube-Finch-Config-Data, + X-Youtube-Finch-Hash-Data, X-YouTube-Lava-Device-Context, X-YouTube-VVT, X-YouTube-Page-CL, + X-YouTube-Page-Label, X-YouTube-Page-Timestamp, X-Compass-Routing-Destination, + x-framework-xsrf-token, X-Goog-Meeting-ABR, X-Goog-Meeting-Botguardid, X-Goog-Meeting-Bot-Info, + X-Goog-Meeting-ClientInfo, X-Goog-Meeting-ClientVersion, X-Goog-Meeting-Debugid, + X-Goog-Meeting-Identifier, X-Goog-Meeting-Interop-Cohorts, X-Goog-Meeting-Interop-Type, + X-Goog-Meeting-OidcIdToken, X-Goog-Meeting-RtcClient, X-Goog-Meeting-StartSource, + X-Goog-Meeting-Token, X-Goog-Meeting-Viewer-Token, X-Goog-Healthcare-Audit-First-Party-Application-Access, + Prefer, X-Client-Data, x-sdm-id-token, X-Sfdc-Authorization, MIME-Version, + Content-Transfer-Encoding, X-Earth-Engine-App-ID-Token, X-Earth-Engine-Computation-Profile, + X-Earth-Engine-Computation-Profiling, X-Play-Console-Experiments-Override, + X-Play-Console-Session-Id, x-alkali-account-key, x-alkali-application-key, + x-alkali-auth-apps-namespace, x-alkali-auth-entities-namespace, x-alkali-auth-entity, + x-alkali-client-locale, EES-S7E-MODE, cast-device-capabilities, X-Server-Timeout, + x-foyer-client-environment, x-goog-greenenergyuserappservice-metadata, x-goog-sherlog-context, + X-Server-Token, x-rfui-request-context, x-goog-nest-jwt, X-Cloud-Trace-Context, + traceparent, x-goog-chat-space-id, x-goog-pan-request-context, X-AppInt-Credentials + Access-Control-Allow-Methods: + - GET,HEAD,OPTIONS + Access-Control-Allow-Origin: + - '*' + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Cache-Control: + - private, max-age=0 + Content-Disposition: + - attachment; filename="features.geojson" + Content-Length: + - '1149' + Content-Security-Policy: + - sandbox + - default-src 'none' + - frame-ancestors 'none' + Content-Type: + - application/octet-stream + Cross-Origin-Embedder-Policy: + - require-corp + Cross-Origin-Opener-Policy: + - same-origin + Cross-Origin-Resource-Policy: + - same-site + Date: + - Wed, 21 Jan 2026 15:36:51 GMT + Expires: + - Wed, 21 Jan 2026 15:36:51 GMT + Last-Modified: + - Wed, 21 Jan 2026 14:21:46 GMT + Server: + - UploadServer + X-Content-Security-Policy: + - sandbox + X-Content-Type-Options: + - nosniff + X-GUploader-UploadID: + - AJRbA5W0Cq-k7b04ZdoF-OEEtJyLFxuomTtLGeiLvKTkgGpAeQ-XxE3t9sHHaCLfGf3eqnU + X-Goog-Hash: + - crc32c=hrZfGQ== + status: + code: 200 + message: OK +version: 1 diff --git a/tests/projects/conflation/cover_image.jpg b/tests/projects/conflation/cover_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31883049c1ab75a91ac2b2f427837c4649ced22f GIT binary patch literal 34830 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 A`~Uy| literal 0 HcmV?d00001 diff --git a/tests/projects/conflation/exports/expected_project_aggregated_result_modified.csv b/tests/projects/conflation/exports/expected_project_aggregated_result_modified.csv new file mode 100644 index 0000000..9329342 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_aggregated_result_modified.csv @@ -0,0 +1,5 @@ +idx,task_id,0_count,1_count,2_count,3_count,total_count,0_share,1_share,2_share,3_share,agreement,quadkey,geom,tile_z,reference +0,t1,0,1,0,0,1,0.0,1.0,0.0,0.0,,,"MULTIPOLYGON(((-99.0960703975439 19.4260629712692,-99.0960703975439 19.4258370781538,-99.0958707900499 19.4258370781538,-99.0958707900499 19.4260629712692,-99.0960703975439 19.4260629712692)))",,"[{""numberIntersecting"": 0}]" +1,t2,1,0,0,0,1,1.0,0.0,0.0,0.0,,,"MULTIPOLYGON(((-99.096234519261 19.4256739329314,-99.096234519261 19.4254396728378,-99.0960570903775 19.4254396728378,-99.0960570903775 19.4256739329314,-99.096234519261 19.4256739329314)))",,"[{""numberIntersecting"": 0}]" +2,t3,1,0,0,0,1,1.0,0.0,0.0,0.0,,,"MULTIPOLYGON(((-99.0945557822443 19.4253619867497,-99.0945557822443 19.424958657374,-99.0942564104523 19.424958657374,-99.0942564104523 19.4253619867497,-99.0945557822443 19.4253619867497)))",,"[{""osmId"": 1158869168, ""osmType"": ""ways_poly"", ""version"": 1, ""numberIntersecting"": 1}]" +3,t4,0,0,0,1,1,0.0,0.0,0.0,1.0,,,"MULTIPOLYGON(((-99.0934675895399 19.4222204725853,-99.0934675895399 19.4220188041236,-99.0933535431433 19.4220188041236,-99.0933535431433 19.4222204725853,-99.0934675895399 19.4222204725853)))",,"[{""numberIntersecting"": 4}]" diff --git a/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson b/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson new file mode 100644 index 0000000..3878c17 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson @@ -0,0 +1 @@ +{"type": "FeatureCollection", "name": "tmp4mcoqzc0", "features": [{"type": "Feature", "properties": {"idx": 0.0, "task_id": "t1", "0_count": 0.0, "1_count": 1.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 0.0, "1_share": 1.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"numberIntersecting": 0}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0960703975439, 19.4260629712692], [-99.0960703975439, 19.4258370781538], [-99.0958707900499, 19.4258370781538], [-99.0958707900499, 19.4260629712692], [-99.0960703975439, 19.4260629712692]]]]}}, {"type": "Feature", "properties": {"idx": 1.0, "task_id": "t2", "0_count": 1.0, "1_count": 0.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 1.0, "1_share": 0.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"numberIntersecting": 0}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.096234519261, 19.4256739329314], [-99.096234519261, 19.4254396728378], [-99.0960570903775, 19.4254396728378], [-99.0960570903775, 19.4256739329314], [-99.096234519261, 19.4256739329314]]]]}}, {"type": "Feature", "properties": {"idx": 2.0, "task_id": "t3", "0_count": 1.0, "1_count": 0.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 1.0, "1_share": 0.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"osmId": 1158869168, "osmType": "ways_poly", "version": 1, "numberIntersecting": 1}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0945557822443, 19.4253619867497], [-99.0945557822443, 19.424958657374], [-99.0942564104523, 19.424958657374], [-99.0942564104523, 19.4253619867497], [-99.0945557822443, 19.4253619867497]]]]}}, {"type": "Feature", "properties": {"idx": 3.0, "task_id": "t4", "0_count": 0.0, "1_count": 0.0, "2_count": 0.0, "3_count": 1.0, "total_count": 1.0, "0_share": 0.0, "1_share": 0.0, "2_share": 0.0, "3_share": 1.0, "reference": [{"numberIntersecting": 4}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0934675895399, 19.4222204725853], [-99.0934675895399, 19.4220188041236], [-99.0933535431433, 19.4220188041236], [-99.0933535431433, 19.4222204725853], [-99.0934675895399, 19.4222204725853]]]]}}]} \ No newline at end of file diff --git a/tests/projects/conflation/exports/expected_project_groups_modified.csv b/tests/projects/conflation/exports/expected_project_groups_modified.csv new file mode 100644 index 0000000..beb5554 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_groups_modified.csv @@ -0,0 +1,2 @@ +,group_id,project_id,number_of_tasks,required_count,finished_count,progress,total_area,time_spent_max_allowed,number_of_users_required +0,g100,01K339HAWZCTCBRVQMQFWRTHXX,4,3,0,0,0.0026785353186614,24.4,3 diff --git a/tests/projects/conflation/exports/expected_project_history.csv b/tests/projects/conflation/exports/expected_project_history.csv new file mode 100644 index 0000000..9608953 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_history.csv @@ -0,0 +1,2 @@ +day,number_of_results,number_of_results_progress,cum_number_of_results,cum_number_of_results_progress,progress,cum_progress,number_of_users,number_of_new_users,cum_number_of_users,project_id +2026-01-21,4,4,4,4,0.3333333333333333,0.3333333333333333,1,1,1,01K339HAWZCTCBRVQMQFWRTHXX diff --git a/tests/projects/conflation/exports/expected_project_result_modified.csv b/tests/projects/conflation/exports/expected_project_result_modified.csv new file mode 100644 index 0000000..972caaa --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_result_modified.csv @@ -0,0 +1,5 @@ +,project_id,group_id,task_id,user_id,timestamp,start_time,end_time,app_version,client_type,result,reference,username +0,01K339HAWZCTCBRVQMQFWRTHXX,g100,t1,01K6CPB1ETTF7MT9EAAQDQM4A9,2026-01-21 14:38:10.783+00,2026-01-21 14:38:10.783+00,2026-01-21 14:38:33.619+00,0.3.0-dev,web,1,"{""numberIntersecting"": 0}",Ram Bahadur +1,01K339HAWZCTCBRVQMQFWRTHXX,g100,t2,01K6CPB1ETTF7MT9EAAQDQM4A9,2026-01-21 14:38:10.783+00,2026-01-21 14:38:10.783+00,2026-01-21 14:38:33.619+00,0.3.0-dev,web,0,"{""numberIntersecting"": 0}",Ram Bahadur +2,01K339HAWZCTCBRVQMQFWRTHXX,g100,t3,01K6CPB1ETTF7MT9EAAQDQM4A9,2026-01-21 14:38:10.783+00,2026-01-21 14:38:10.783+00,2026-01-21 14:38:33.619+00,0.3.0-dev,web,0,"{""osmId"": 1158869168, ""osmType"": ""ways_poly"", ""version"": 1, ""numberIntersecting"": 1}",Ram Bahadur +3,01K339HAWZCTCBRVQMQFWRTHXX,g100,t4,01K6CPB1ETTF7MT9EAAQDQM4A9,2026-01-21 14:38:10.783+00,2026-01-21 14:38:10.783+00,2026-01-21 14:38:33.619+00,0.3.0-dev,web,3,"{""numberIntersecting"": 4}",Ram Bahadur diff --git a/tests/projects/conflation/exports/expected_project_tasks_modified.csv b/tests/projects/conflation/exports/expected_project_tasks_modified.csv new file mode 100644 index 0000000..5470fd9 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_tasks_modified.csv @@ -0,0 +1,5 @@ +,project_id,group_id,task_id,geom,tile_z +0,01K339HAWZCTCBRVQMQFWRTHXX,g100,t1,"MULTIPOLYGON(((-99.0960703975439 19.4260629712692,-99.0960703975439 19.4258370781538,-99.0958707900499 19.4258370781538,-99.0958707900499 19.4260629712692,-99.0960703975439 19.4260629712692)))", +1,01K339HAWZCTCBRVQMQFWRTHXX,g100,t2,"MULTIPOLYGON(((-99.096234519261 19.4256739329314,-99.096234519261 19.4254396728378,-99.0960570903775 19.4254396728378,-99.0960570903775 19.4256739329314,-99.096234519261 19.4256739329314)))", +2,01K339HAWZCTCBRVQMQFWRTHXX,g100,t3,"MULTIPOLYGON(((-99.0945557822443 19.4253619867497,-99.0945557822443 19.424958657374,-99.0942564104523 19.424958657374,-99.0942564104523 19.4253619867497,-99.0945557822443 19.4253619867497)))", +3,01K339HAWZCTCBRVQMQFWRTHXX,g100,t4,"MULTIPOLYGON(((-99.0934675895399 19.4222204725853,-99.0934675895399 19.4220188041236,-99.0933535431433 19.4220188041236,-99.0933535431433 19.4222204725853,-99.0934675895399 19.4222204725853)))", diff --git a/tests/projects/conflation/exports/expected_project_users.csv b/tests/projects/conflation/exports/expected_project_users.csv new file mode 100644 index 0000000..ec18913 --- /dev/null +++ b/tests/projects/conflation/exports/expected_project_users.csv @@ -0,0 +1,2 @@ +idx,project_id,user_id,username,groups_completed,total_contributions,agreeing_contributions,disagreeing_contributions,simple_agreement_score +0,01K339HAWZCTCBRVQMQFWRTHXX,01K6CPB1ETTF7MT9EAAQDQM4A9,Ram Bahadur,1,4,0,0, diff --git a/tests/projects/conflation/features.geojson b/tests/projects/conflation/features.geojson new file mode 100644 index 0000000..1335fe3 --- /dev/null +++ b/tests/projects/conflation/features.geojson @@ -0,0 +1 @@ +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09607039754393,19.42606297126916],[-99.09607039754393,19.42583707815382],[-99.09587079004991,19.42583707815382],[-99.09587079004991,19.42606297126916],[-99.09607039754393,19.42606297126916]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.096234519261,19.42567393293139],[-99.096234519261,19.42543967283784],[-99.09605709037753,19.42543967283784],[-99.09605709037753,19.42567393293139],[-99.096234519261,19.42567393293139]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09455578224427,19.42536198674972],[-99.09455578224427,19.42495865737405],[-99.09425641045227,19.42495865737405],[-99.09425641045227,19.42536198674972],[-99.09455578224427,19.42536198674972]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09346758953988,19.42222047258528],[-99.09346758953988,19.422018804123567],[-99.09335354314331,19.422018804123567],[-99.09335354314331,19.42222047258528],[-99.09346758953988,19.42222047258528]]],"type":"Polygon"}}]} \ No newline at end of file diff --git a/tests/projects/conflation/project_data.json5 b/tests/projects/conflation/project_data.json5 new file mode 100644 index 0000000..e21a15e --- /dev/null +++ b/tests/projects/conflation/project_data.json5 @@ -0,0 +1,385 @@ +{ + contributor_user_firebase_id: '01K6CPB1ETTF7MT9EAAQDQM4A9', + assets: { + image: 'assets/tests/projects/conflation/cover_image.jpg', + }, + // Create organization + create_organization: { + clientId: '01K6CKWDFX8HZFY5PHJZN1AYH9', + name: 'Togglecorp', + description: 'Togglecorp (test) organization', + }, + // Create tutorial + create_tutorial: { + clientId: '01K4MQ88R61EDAMS0K0TW0N17A', + name: 'Conflation Tutorial', + }, + update_tutorial: { + clientId: '01K4MQ88R61EDAMS0K0TW0N17A', + name: 'Conflation Tutorial', + scenarios: [ + { + create: { + clientId: '01K4S0NP93KN45MAX2Z5N6PVGX', + hintDescription: 'Click Yes', + hintIcon: 'HELP_OUTLINE', + hintTitle: 'This building looks correct', + instructionsDescription: 'This building looks correct', + instructionsIcon: 'CLOSE_OUTLINE', + instructionsTitle: 'Correct building', + scenarioPageNumber: 1, + successDescription: 'This building is correct', + successIcon: 'CHECKMARK_OUTLINE', + successTitle: 'Well done', + tasks: [ + { + clientId: '01K4S0NP93AQKZ6S558VPVQS19', + projectTypeSpecifics: { + conflation: { + identifier: 1098299960, + objectGeometry: '{"type":"Polygon","coordinates":[[[84.001574,28.1935348],[84.001576,28.1934266],[84.0016578,28.1934278],[84.0016558,28.1935359],[84.001574,28.1935348]]]}', + }, + }, + reference: 1, + }, + ], + }, + }, + ], + informationPages: [ + { + create: { + clientId: '01K4S214M1SSN4N862GYP0BA12', + pageNumber: 1, + title: 'Compare building footprints', + blocks: [ + { + blockNumber: 1, + blockType: 'TEXT', + clientId: '01K4S21NP6BG28SYXV0W6EYRVZ', + text: 'It might look something like this as well', + }, + { + blockNumber: 2, + blockType: 'TEXT', + clientId: '01K4S21W8S2EMAH4GQZRXPPE6K', + text: 'It might look something like this as well', + }, + ], + }, + }, + ], + }, + // Create project + create_project: { + clientId: '01K339HAWZCTCBRVQMQFWRTHXX', + topic: 'fAIr', + region: 'Manbhawan', + projectNumber: 2, + projectType: 'CONFLATION', + projectInstruction: 'Compare buildings', + lookFor: 'building', + description: 'This is a conflation project.', + requestingOrganization: 'Togglecorp', + }, + update_project: { + clientId: '01K339HAWZCTCBRVQMQFWRTHXX', + additionalInfoUrl: 'https://fair.hotosm.org', + description: 'This is a conflation project with an extended description', + verificationNumber: 3, + projectInstruction: 'Compare buildings', + groupSize: 25, + team: null, + topic: 'fAIr', + tutorial: null, + maxTasksPerUser: 30, + projectNumber: 2, + region: 'Manbhawan', + image: null, + projectTypeSpecifics: { + conflation: { + objectSource: { + objectGeojsonUrl: 'https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f', + }, + tileServerProperty: { + name: 'BING', + bing: { + credits: '© 2019 Microsoft Corporation, Earthstar Geographics SIO', + }, + }, + }, + }, + }, + update_processed_project: { + clientId: '01K339HAWZCTCBRVQMQFWRTHXX', + additionalInfoUrl: 'https://fair.hotosm.org', + description: 'This is a conflation project with an extended description', + projectInstruction: 'Compare buildings', + projectNumber: 2, + region: 'Manbhawan', + topic: 'fAIr', + // NOTE: These values will be injected by test scripts + image: null, + tutorial: null, + team: null, + }, + // Expected tutorial + expected_tutorial_data: { + contributorCount: 0, + informationPages: [ + { + blocks: [ + { + blockNumber: 1, + blockType: 'text', + textDescription: 'It might look something like this as well' + }, + { + blockNumber: 2, + blockType: 'text', + textDescription: 'It might look something like this as well' + } + ], + pageNumber: 1, + title: 'Compare building footprints' + } + ], + inputGeometries: '', + lookFor: 'building', + name: 'Conflation Tutorial', + progress: 0, + projectDetails: 'This is a conflation project with an extended description', + projectId: 'tutorial_01K4MQ88R61EDAMS0K0TW0N17A', + projectTopicKey: 'conflation tutorial', + projectType: 8, + screens: [ + { + hint: { + description: 'Click Yes', + icon: 'help-outline', + title: 'This building looks correct' + }, + instructions: { + description: 'This building looks correct', + icon: 'close-outline', + title: 'Correct building' + }, + success: { + description: 'This building is correct', + icon: 'checkmark-outline', + title: 'Well done' + } + } + ], + status: 'tutorial', + tileServer: { + apiKey: 'dummy-bing', + credits: '© 2019 Microsoft Corporation, Earthstar Geographics SIO', + name: 'bing', + url: 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}' + }, + tutorialDraftId: '', + zoomLevel: 18, + }, + expected_tutorial_groups_data: { + '101': { + finishedCount: 0, + groupId: 101, + numberOfTasks: 1, + progress: 0, + projectId: 'tutorial_01K4MQ88R61EDAMS0K0TW0N17A', + requiredCount: 0, + }, + }, + expected_tutorial_tasks_data: { + // NOTE: The tasks have been decoded + '101': [ + { + taskId: 't1', + geojson: { + coordinates: [ + [ + [84.001574, 28.1935348], + [84.001576, 28.1934266], + [84.0016578, 28.1934278], + [84.0016558, 28.1935359], + [84.001574, 28.1935348], + ], + ], + type: 'Polygon', + }, + properties: { + id: 1098299960, + reference: 1, + screen: 1, + }, + // FIXME(tnagorra): The geometry was wrong in previous version (Added space after POLYGON and longitude values) + geometry: 'POLYGON ((84.001574 28.1935348,84.001576 28.1934266,84.0016578 28.1934278,84.0016558 28.1935359,84.001574 28.1935348))', + }, + ], + }, + // Expected project + expected_project_data: { + contributorCount: 0, + created: "2026-01-21T13:49:30.764081+00:00", + createdBy: "01K6CPB1ETTF7MT9EAAQDQM4A9", + groupMaxSize: 25, + groupSize: 25, + isFeatured: false, + language: "en-us", + lookFor: "building", + manualUrl: "https://fair.hotosm.org", + maxTasksPerUser: 30, + name: "Conflate Features - fAIr - Manbhawan (2) Togglecorp", + progress: 0, + projectDetails: "This is a conflation project with an extended description", + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + projectInstruction: "Compare buildings", + projectNumber: 2, + projectRegion: "Manbhawan", + projectTopic: "fAIr", + projectTopicKey: "conflate features - fair - manbhawan (2) togglecorp", + projectType: 8, + requestingOrganisation: "Togglecorp", + requiredResults: 12, + resultCount: 0, + status: "active", + tileServer: { + apiKey: "dummy-bing", + credits: "© 2019 Microsoft Corporation, Earthstar Geographics SIO", + name: "bing", + url: "https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}" + }, + tutorialId: "tutorial_01K4MQ88R61EDAMS0K0TW0N17A", + verificationNumber: 3 + }, + expected_project_groups_data: { + g100: { + finishedCount: 0, + groupId: "g100", + numberOfTasks: 4, + progress: 0, + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + requiredCount: 3 + } + }, + expected_project_tasks_data: { + g100: [ + { + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + taskId: "t1", + geojson: { + type: "Polygon", + coordinates: [ + [ + [-99.0960703975439, 19.4260629712692], + [-99.0960703975439, 19.4258370781538], + [-99.0958707900499, 19.4258370781538], + [-99.0958707900499, 19.4260629712692], + [-99.0960703975439, 19.4260629712692] + ] + ] + } + }, + { + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + taskId: "t2", + geojson: { + type: "Polygon", + coordinates: [ + [ + [-99.096234519261, 19.4256739329314], + [-99.096234519261, 19.4254396728378], + [-99.0960570903775, 19.4254396728378], + [-99.0960570903775, 19.4256739329314], + [-99.096234519261, 19.4256739329314] + ] + ] + } + }, + { + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + taskId: "t3", + geojson: { + type: "Polygon", + coordinates: [ + [ + [-99.0945557822443, 19.4253619867497], + [-99.0945557822443, 19.424958657374], + [-99.0942564104523, 19.424958657374], + [-99.0942564104523, 19.4253619867497], + [-99.0945557822443, 19.4253619867497] + ] + ] + } + }, + { + projectId: "01K339HAWZCTCBRVQMQFWRTHXX", + taskId: "t4", + geojson: { + type: "Polygon", + coordinates: [ + [ + [-99.0934675895399, 19.4222204725853], + [-99.0934675895399, 19.4220188041236], + [-99.0933535431433, 19.4220188041236], + [-99.0933535431433, 19.4222204725853], + [-99.0934675895399, 19.4222204725853] + ] + ] + } + } + ] + }, + // Create contributor group + create_contributor_user_group: [ + { + clientId: '01K49J0QPCZM2JCNC9AEE6HT8Y', + name: 'User Group 01', + description: 'First user group', + }, + ], + create_results: { + g100: { + '01K6CPB1ETTF7MT9EAAQDQM4A9': { + startTime: '2026-01-21T14:38:10.783Z', + endTime: '2026-01-21T14:38:33.619Z', + appVersion: '0.3.0-dev', + clientType: 'web', + reference: { + t1: { numberIntersecting: 0 }, + t2: { numberIntersecting: 0 }, + t3: { + numberIntersecting: 1, + osmId: 1158869168, + osmType: 'ways_poly', + version: 1, + }, + t4: { numberIntersecting: 4 }, + }, + results: { + t1: 1, + t2: 0, + t3: 0, + t4: 3, + }, + }, + }, + }, + expected_pulled_results_data: { + mapping_session_count: 1, + mapping_session_results_count: 4, + mapping_session_user_groups_count: 0, + progress: 33, + }, + expected_project_exports_data: { + aggregated_results: 'assets/tests/projects/conflation/exports/expected_project_aggregated_result_modified.csv', + aggregated_results_with_geometry: 'assets/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson', + results: 'assets/tests/projects/conflation/exports/expected_project_result_modified.csv', + history: 'assets/tests/projects/conflation/exports/expected_project_history.csv', + groups: 'assets/tests/projects/conflation/exports/expected_project_groups_modified.csv', + tasks: 'assets/tests/projects/conflation/exports/expected_project_tasks_modified.csv', + users: 'assets/tests/projects/conflation/exports/expected_project_users.csv', + area_of_interest: 'assets/tests/projects/conflation/exports/expected_project_aoi.geojson', + }, +} From b3e56bf31d7c7f474c411c82d1c194f4f828bf9c Mon Sep 17 00:00:00 2001 From: ofritz Date: Thu, 22 Jan 2026 15:39:55 +0100 Subject: [PATCH 2/2] feat(conflation): prettier formatting --- ...rojectE2E.test_conflation_project_e2e.yaml | 354 +++++++++--------- ...ated_result_with_geometry_modified.geojson | 138 ++++++- tests/projects/conflation/features.geojson | 70 +++- tests/projects/conflation/project_data.json5 | 134 +++---- 4 files changed, 450 insertions(+), 246 deletions(-) diff --git a/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml b/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml index f07784f..f12c3f1 100644 --- a/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml +++ b/tests/projects/conflation/cassette/TestConflationProjectE2E.test_conflation_project_e2e.yaml @@ -1,179 +1,179 @@ interactions: -- request: - body: null - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - User-Agent: - - python-requests/2.32.5 - method: GET - uri: https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f - response: - body: - string: '' - headers: - Accept-CH: - - Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, - Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factors, Sec-CH-UA-Platform, - Sec-CH-UA-Platform-Version - Alt-Svc: - - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 - Cache-Control: - - no-cache, no-store, max-age=0, must-revalidate - Content-Length: - - '0' - Content-Security-Policy: - - script-src 'nonce-7pwRZRdV3luL9vhndcbIWQ' 'unsafe-inline';object-src 'none';base-uri - 'self';report-uri /_/DriveUntrustedContentHttp/cspreport;worker-src 'self' - - require-trusted-types-for 'script';report-uri /_/DriveUntrustedContentHttp/cspreport - Content-Type: - - application/binary - Cross-Origin-Opener-Policy: - - same-origin - Date: - - Wed, 21 Jan 2026 15:36:50 GMT - Expires: - - Mon, 01 Jan 1990 00:00:00 GMT - Location: - - https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download - Permissions-Policy: - - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*, - ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factors=*, ch-ua-platform=*, ch-ua-platform-version=* - Pragma: - - no-cache - Server: - - ESF - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Origin - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-XSS-Protection: - - '0' - status: - code: 303 - message: See Other -- request: - body: null - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - User-Agent: - - python-requests/2.32.5 - method: GET - uri: https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download - response: - body: - string: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09607039754393,19.42606297126916],[-99.09607039754393,19.42583707815382],[-99.09587079004991,19.42583707815382],[-99.09587079004991,19.42606297126916],[-99.09607039754393,19.42606297126916]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.096234519261,19.42567393293139],[-99.096234519261,19.42543967283784],[-99.09605709037753,19.42543967283784],[-99.09605709037753,19.42567393293139],[-99.096234519261,19.42567393293139]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09455578224427,19.42536198674972],[-99.09455578224427,19.42495865737405],[-99.09425641045227,19.42495865737405],[-99.09425641045227,19.42536198674972],[-99.09455578224427,19.42536198674972]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09346758953988,19.42222047258528],[-99.09346758953988,19.422018804123567],[-99.09335354314331,19.422018804123567],[-99.09335354314331,19.42222047258528],[-99.09346758953988,19.42222047258528]]],"type":"Polygon"}}]}' - headers: - Accept-Ranges: - - bytes - Access-Control-Allow-Credentials: - - 'false' - Access-Control-Allow-Headers: - - Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, - Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, - Content-Type, Date, developer-token, financial-institution-id, X-Goog-Sn-Metadata, - X-Goog-Sn-PatientId, GData-Version, google-cloud-resource-prefix, linked-customer-id, - login-customer-id, x-goog-request-params, Host, If-Match, If-Modified-Since, - If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, request-id, - Signature, Signature-Agent, Signature-Input, Slug, Transfer-Encoding, User-Agent, - hotrod-board-name, hotrod-chrome-cpu-model, hotrod-chrome-processors, Want-Digest, - X-Ad-Manager-Impersonation, x-chrome-connected, X-ClientDetails, X-Client-Pctx, - X-Client-Version, x-debug-settings-metadata, X-Firebase-AppId, X-Firebase-AppVersion, - X-Firebase-Locale, X-Goog-Firebase-Installations-Auth, X-Firebase-Client, - X-Firebase-Client-Log-Type, X-Firebase-GMPID, X-Firebase-Auth-Token, X-Firebase-AppCheck, - X-Firebase-RC-Fetch-Type, X-Firebase-Token, X-Goog-Drive-Client-Version, X-Goog-Drive-Resource-Keys, - X-GData-Client, X-GData-Key, X-GoogApps-Allowed-Domains, X-Goog-AdX-Buyer-Impersonation, - X-Goog-Api-Client, X-Goog-Visibilities, X-Goog-AuthUser, X-Google-EOM, x-goog-ext-124712974-jspb, - x-goog-ext-467253834-jspb, x-goog-ext-353267353-bin, x-goog-ext-353267353-jspb, - x-goog-ext-251363160-jspb, x-goog-ext-259736195-jspb, x-goog-ext-477772811-jspb, - x-goog-ext-359275022-bin, x-goog-ext-328800237-jspb, x-goog-ext-198889211-bin, - x-goog-ext-202735639-bin, x-goog-ext-223261916-bin, x-goog-ext-223435598-bin, - x-goog-ext-233818517-bin, x-goog-ext-202964622-bin, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, - X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Request-Reason, X-Goog-Request-Time, - X-Goog-Experiments, x-goog-iam-authority-selector, x-goog-iam-authorization-token, - X-Goog-Spatula, X-Goog-Travel-Bgr, X-Goog-Travel-Settings, X-Goog-Upload-Command, - X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, - X-Goog-Upload-File-Name, X-Goog-Upload-Header-Content-Encoding, X-Goog-Upload-Header-Content-Length, - X-Goog-Upload-Header-Content-Type, X-Goog-Upload-Header-Transfer-Encoding, - X-Goog-Upload-Offset, X-Goog-Upload-Protocol, x-goog-user-project, X-Goog-Visitor-Id, - X-Goog-FieldMask, X-Google-Project-Override, x-goog-maps-api-salt, x-goog-maps-api-signature, - x-goog-maps-client-id, X-Goog-Api-Key, x-goog-spanner-database-role, X-HTTP-Method-Override, - X-JavaScript-User-Agent, X-Pan-Versionid, X-Proxied-User-IP, X-Origin, X-Referer, - X-Requested-With, X-Stadia-Client-Context, X-Upload-Content-Length, X-Upload-Content-Type, - X-Use-Alt-Service, X-Use-HTTP-Status-Code-Override, X-Ios-Bundle-Identifier, - X-Places-Ios-Sdk, X-Android-Package, X-Android-Cert, X-Places-Android-Sdk, - X-Goog-Maps-Ios-Uuid, X-Goog-Maps-Android-Uuid, X-Ariane-Xsrf-Token, X-YouTube-Bootstrap-Logged-In, - X-Youtube-Client-Name, X-Youtube-Client-Version, X-Youtube-Finch-Config-Data, - X-Youtube-Finch-Hash-Data, X-YouTube-Lava-Device-Context, X-YouTube-VVT, X-YouTube-Page-CL, - X-YouTube-Page-Label, X-YouTube-Page-Timestamp, X-Compass-Routing-Destination, - x-framework-xsrf-token, X-Goog-Meeting-ABR, X-Goog-Meeting-Botguardid, X-Goog-Meeting-Bot-Info, - X-Goog-Meeting-ClientInfo, X-Goog-Meeting-ClientVersion, X-Goog-Meeting-Debugid, - X-Goog-Meeting-Identifier, X-Goog-Meeting-Interop-Cohorts, X-Goog-Meeting-Interop-Type, - X-Goog-Meeting-OidcIdToken, X-Goog-Meeting-RtcClient, X-Goog-Meeting-StartSource, - X-Goog-Meeting-Token, X-Goog-Meeting-Viewer-Token, X-Goog-Healthcare-Audit-First-Party-Application-Access, - Prefer, X-Client-Data, x-sdm-id-token, X-Sfdc-Authorization, MIME-Version, - Content-Transfer-Encoding, X-Earth-Engine-App-ID-Token, X-Earth-Engine-Computation-Profile, - X-Earth-Engine-Computation-Profiling, X-Play-Console-Experiments-Override, - X-Play-Console-Session-Id, x-alkali-account-key, x-alkali-application-key, - x-alkali-auth-apps-namespace, x-alkali-auth-entities-namespace, x-alkali-auth-entity, - x-alkali-client-locale, EES-S7E-MODE, cast-device-capabilities, X-Server-Timeout, - x-foyer-client-environment, x-goog-greenenergyuserappservice-metadata, x-goog-sherlog-context, - X-Server-Token, x-rfui-request-context, x-goog-nest-jwt, X-Cloud-Trace-Context, - traceparent, x-goog-chat-space-id, x-goog-pan-request-context, X-AppInt-Credentials - Access-Control-Allow-Methods: - - GET,HEAD,OPTIONS - Access-Control-Allow-Origin: - - '*' - Alt-Svc: - - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 - Cache-Control: - - private, max-age=0 - Content-Disposition: - - attachment; filename="features.geojson" - Content-Length: - - '1149' - Content-Security-Policy: - - sandbox - - default-src 'none' - - frame-ancestors 'none' - Content-Type: - - application/octet-stream - Cross-Origin-Embedder-Policy: - - require-corp - Cross-Origin-Opener-Policy: - - same-origin - Cross-Origin-Resource-Policy: - - same-site - Date: - - Wed, 21 Jan 2026 15:36:51 GMT - Expires: - - Wed, 21 Jan 2026 15:36:51 GMT - Last-Modified: - - Wed, 21 Jan 2026 14:21:46 GMT - Server: - - UploadServer - X-Content-Security-Policy: - - sandbox - X-Content-Type-Options: - - nosniff - X-GUploader-UploadID: - - AJRbA5W0Cq-k7b04ZdoF-OEEtJyLFxuomTtLGeiLvKTkgGpAeQ-XxE3t9sHHaCLfGf3eqnU - X-Goog-Hash: - - crc32c=hrZfGQ== - status: - code: 200 - message: OK + - request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.5 + method: GET + uri: https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f + response: + body: + string: '' + headers: + Accept-CH: + - Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, + Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factors, Sec-CH-UA-Platform, + Sec-CH-UA-Platform-Version + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Content-Length: + - '0' + Content-Security-Policy: + - script-src 'nonce-7pwRZRdV3luL9vhndcbIWQ' 'unsafe-inline';object-src 'none';base-uri + 'self';report-uri /_/DriveUntrustedContentHttp/cspreport;worker-src 'self' + - require-trusted-types-for 'script';report-uri /_/DriveUntrustedContentHttp/cspreport + Content-Type: + - application/binary + Cross-Origin-Opener-Policy: + - same-origin + Date: + - Wed, 21 Jan 2026 15:36:50 GMT + Expires: + - Mon, 01 Jan 1990 00:00:00 GMT + Location: + - https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download + Permissions-Policy: + - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*, + ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factors=*, ch-ua-platform=*, ch-ua-platform-version=* + Pragma: + - no-cache + Server: + - ESF + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-XSS-Protection: + - '0' + status: + code: 303 + message: See Other + - request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.5 + method: GET + uri: https://drive.usercontent.google.com/download?id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f&export=download + response: + body: + string: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09607039754393,19.42606297126916],[-99.09607039754393,19.42583707815382],[-99.09587079004991,19.42583707815382],[-99.09587079004991,19.42606297126916],[-99.09607039754393,19.42606297126916]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.096234519261,19.42567393293139],[-99.096234519261,19.42543967283784],[-99.09605709037753,19.42543967283784],[-99.09605709037753,19.42567393293139],[-99.096234519261,19.42567393293139]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09455578224427,19.42536198674972],[-99.09455578224427,19.42495865737405],[-99.09425641045227,19.42495865737405],[-99.09425641045227,19.42536198674972],[-99.09455578224427,19.42536198674972]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09346758953988,19.42222047258528],[-99.09346758953988,19.422018804123567],[-99.09335354314331,19.422018804123567],[-99.09335354314331,19.42222047258528],[-99.09346758953988,19.42222047258528]]],"type":"Polygon"}}]}' + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Credentials: + - 'false' + Access-Control-Allow-Headers: + - Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, + Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, + Content-Type, Date, developer-token, financial-institution-id, X-Goog-Sn-Metadata, + X-Goog-Sn-PatientId, GData-Version, google-cloud-resource-prefix, linked-customer-id, + login-customer-id, x-goog-request-params, Host, If-Match, If-Modified-Since, + If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, request-id, + Signature, Signature-Agent, Signature-Input, Slug, Transfer-Encoding, User-Agent, + hotrod-board-name, hotrod-chrome-cpu-model, hotrod-chrome-processors, Want-Digest, + X-Ad-Manager-Impersonation, x-chrome-connected, X-ClientDetails, X-Client-Pctx, + X-Client-Version, x-debug-settings-metadata, X-Firebase-AppId, X-Firebase-AppVersion, + X-Firebase-Locale, X-Goog-Firebase-Installations-Auth, X-Firebase-Client, + X-Firebase-Client-Log-Type, X-Firebase-GMPID, X-Firebase-Auth-Token, X-Firebase-AppCheck, + X-Firebase-RC-Fetch-Type, X-Firebase-Token, X-Goog-Drive-Client-Version, X-Goog-Drive-Resource-Keys, + X-GData-Client, X-GData-Key, X-GoogApps-Allowed-Domains, X-Goog-AdX-Buyer-Impersonation, + X-Goog-Api-Client, X-Goog-Visibilities, X-Goog-AuthUser, X-Google-EOM, x-goog-ext-124712974-jspb, + x-goog-ext-467253834-jspb, x-goog-ext-353267353-bin, x-goog-ext-353267353-jspb, + x-goog-ext-251363160-jspb, x-goog-ext-259736195-jspb, x-goog-ext-477772811-jspb, + x-goog-ext-359275022-bin, x-goog-ext-328800237-jspb, x-goog-ext-198889211-bin, + x-goog-ext-202735639-bin, x-goog-ext-223261916-bin, x-goog-ext-223435598-bin, + x-goog-ext-233818517-bin, x-goog-ext-202964622-bin, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, + X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Request-Reason, X-Goog-Request-Time, + X-Goog-Experiments, x-goog-iam-authority-selector, x-goog-iam-authorization-token, + X-Goog-Spatula, X-Goog-Travel-Bgr, X-Goog-Travel-Settings, X-Goog-Upload-Command, + X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, + X-Goog-Upload-File-Name, X-Goog-Upload-Header-Content-Encoding, X-Goog-Upload-Header-Content-Length, + X-Goog-Upload-Header-Content-Type, X-Goog-Upload-Header-Transfer-Encoding, + X-Goog-Upload-Offset, X-Goog-Upload-Protocol, x-goog-user-project, X-Goog-Visitor-Id, + X-Goog-FieldMask, X-Google-Project-Override, x-goog-maps-api-salt, x-goog-maps-api-signature, + x-goog-maps-client-id, X-Goog-Api-Key, x-goog-spanner-database-role, X-HTTP-Method-Override, + X-JavaScript-User-Agent, X-Pan-Versionid, X-Proxied-User-IP, X-Origin, X-Referer, + X-Requested-With, X-Stadia-Client-Context, X-Upload-Content-Length, X-Upload-Content-Type, + X-Use-Alt-Service, X-Use-HTTP-Status-Code-Override, X-Ios-Bundle-Identifier, + X-Places-Ios-Sdk, X-Android-Package, X-Android-Cert, X-Places-Android-Sdk, + X-Goog-Maps-Ios-Uuid, X-Goog-Maps-Android-Uuid, X-Ariane-Xsrf-Token, X-YouTube-Bootstrap-Logged-In, + X-Youtube-Client-Name, X-Youtube-Client-Version, X-Youtube-Finch-Config-Data, + X-Youtube-Finch-Hash-Data, X-YouTube-Lava-Device-Context, X-YouTube-VVT, X-YouTube-Page-CL, + X-YouTube-Page-Label, X-YouTube-Page-Timestamp, X-Compass-Routing-Destination, + x-framework-xsrf-token, X-Goog-Meeting-ABR, X-Goog-Meeting-Botguardid, X-Goog-Meeting-Bot-Info, + X-Goog-Meeting-ClientInfo, X-Goog-Meeting-ClientVersion, X-Goog-Meeting-Debugid, + X-Goog-Meeting-Identifier, X-Goog-Meeting-Interop-Cohorts, X-Goog-Meeting-Interop-Type, + X-Goog-Meeting-OidcIdToken, X-Goog-Meeting-RtcClient, X-Goog-Meeting-StartSource, + X-Goog-Meeting-Token, X-Goog-Meeting-Viewer-Token, X-Goog-Healthcare-Audit-First-Party-Application-Access, + Prefer, X-Client-Data, x-sdm-id-token, X-Sfdc-Authorization, MIME-Version, + Content-Transfer-Encoding, X-Earth-Engine-App-ID-Token, X-Earth-Engine-Computation-Profile, + X-Earth-Engine-Computation-Profiling, X-Play-Console-Experiments-Override, + X-Play-Console-Session-Id, x-alkali-account-key, x-alkali-application-key, + x-alkali-auth-apps-namespace, x-alkali-auth-entities-namespace, x-alkali-auth-entity, + x-alkali-client-locale, EES-S7E-MODE, cast-device-capabilities, X-Server-Timeout, + x-foyer-client-environment, x-goog-greenenergyuserappservice-metadata, x-goog-sherlog-context, + X-Server-Token, x-rfui-request-context, x-goog-nest-jwt, X-Cloud-Trace-Context, + traceparent, x-goog-chat-space-id, x-goog-pan-request-context, X-AppInt-Credentials + Access-Control-Allow-Methods: + - GET,HEAD,OPTIONS + Access-Control-Allow-Origin: + - '*' + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Cache-Control: + - private, max-age=0 + Content-Disposition: + - attachment; filename="features.geojson" + Content-Length: + - '1149' + Content-Security-Policy: + - sandbox + - default-src 'none' + - frame-ancestors 'none' + Content-Type: + - application/octet-stream + Cross-Origin-Embedder-Policy: + - require-corp + Cross-Origin-Opener-Policy: + - same-origin + Cross-Origin-Resource-Policy: + - same-site + Date: + - Wed, 21 Jan 2026 15:36:51 GMT + Expires: + - Wed, 21 Jan 2026 15:36:51 GMT + Last-Modified: + - Wed, 21 Jan 2026 14:21:46 GMT + Server: + - UploadServer + X-Content-Security-Policy: + - sandbox + X-Content-Type-Options: + - nosniff + X-GUploader-UploadID: + - AJRbA5W0Cq-k7b04ZdoF-OEEtJyLFxuomTtLGeiLvKTkgGpAeQ-XxE3t9sHHaCLfGf3eqnU + X-Goog-Hash: + - crc32c=hrZfGQ== + status: + code: 200 + message: OK version: 1 diff --git a/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson b/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson index 3878c17..39158c8 100644 --- a/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson +++ b/tests/projects/conflation/exports/expected_project_aggregated_result_with_geometry_modified.geojson @@ -1 +1,137 @@ -{"type": "FeatureCollection", "name": "tmp4mcoqzc0", "features": [{"type": "Feature", "properties": {"idx": 0.0, "task_id": "t1", "0_count": 0.0, "1_count": 1.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 0.0, "1_share": 1.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"numberIntersecting": 0}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0960703975439, 19.4260629712692], [-99.0960703975439, 19.4258370781538], [-99.0958707900499, 19.4258370781538], [-99.0958707900499, 19.4260629712692], [-99.0960703975439, 19.4260629712692]]]]}}, {"type": "Feature", "properties": {"idx": 1.0, "task_id": "t2", "0_count": 1.0, "1_count": 0.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 1.0, "1_share": 0.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"numberIntersecting": 0}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.096234519261, 19.4256739329314], [-99.096234519261, 19.4254396728378], [-99.0960570903775, 19.4254396728378], [-99.0960570903775, 19.4256739329314], [-99.096234519261, 19.4256739329314]]]]}}, {"type": "Feature", "properties": {"idx": 2.0, "task_id": "t3", "0_count": 1.0, "1_count": 0.0, "2_count": 0.0, "3_count": 0.0, "total_count": 1.0, "0_share": 1.0, "1_share": 0.0, "2_share": 0.0, "3_share": 0.0, "reference": [{"osmId": 1158869168, "osmType": "ways_poly", "version": 1, "numberIntersecting": 1}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0945557822443, 19.4253619867497], [-99.0945557822443, 19.424958657374], [-99.0942564104523, 19.424958657374], [-99.0942564104523, 19.4253619867497], [-99.0945557822443, 19.4253619867497]]]]}}, {"type": "Feature", "properties": {"idx": 3.0, "task_id": "t4", "0_count": 0.0, "1_count": 0.0, "2_count": 0.0, "3_count": 1.0, "total_count": 1.0, "0_share": 0.0, "1_share": 0.0, "2_share": 0.0, "3_share": 1.0, "reference": [{"numberIntersecting": 4}]}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-99.0934675895399, 19.4222204725853], [-99.0934675895399, 19.4220188041236], [-99.0933535431433, 19.4220188041236], [-99.0933535431433, 19.4222204725853], [-99.0934675895399, 19.4222204725853]]]]}}]} \ No newline at end of file +{ + "type": "FeatureCollection", + "name": "tmp4mcoqzc0", + "features": [ + { + "type": "Feature", + "properties": { + "idx": 0.0, + "task_id": "t1", + "0_count": 0.0, + "1_count": 1.0, + "2_count": 0.0, + "3_count": 0.0, + "total_count": 1.0, + "0_share": 0.0, + "1_share": 1.0, + "2_share": 0.0, + "3_share": 0.0, + "reference": [{ "numberIntersecting": 0 }] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-99.0960703975439, 19.4260629712692], + [-99.0960703975439, 19.4258370781538], + [-99.0958707900499, 19.4258370781538], + [-99.0958707900499, 19.4260629712692], + [-99.0960703975439, 19.4260629712692] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "idx": 1.0, + "task_id": "t2", + "0_count": 1.0, + "1_count": 0.0, + "2_count": 0.0, + "3_count": 0.0, + "total_count": 1.0, + "0_share": 1.0, + "1_share": 0.0, + "2_share": 0.0, + "3_share": 0.0, + "reference": [{ "numberIntersecting": 0 }] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-99.096234519261, 19.4256739329314], + [-99.096234519261, 19.4254396728378], + [-99.0960570903775, 19.4254396728378], + [-99.0960570903775, 19.4256739329314], + [-99.096234519261, 19.4256739329314] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "idx": 2.0, + "task_id": "t3", + "0_count": 1.0, + "1_count": 0.0, + "2_count": 0.0, + "3_count": 0.0, + "total_count": 1.0, + "0_share": 1.0, + "1_share": 0.0, + "2_share": 0.0, + "3_share": 0.0, + "reference": [ + { + "osmId": 1158869168, + "osmType": "ways_poly", + "version": 1, + "numberIntersecting": 1 + } + ] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-99.0945557822443, 19.4253619867497], + [-99.0945557822443, 19.424958657374], + [-99.0942564104523, 19.424958657374], + [-99.0942564104523, 19.4253619867497], + [-99.0945557822443, 19.4253619867497] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "idx": 3.0, + "task_id": "t4", + "0_count": 0.0, + "1_count": 0.0, + "2_count": 0.0, + "3_count": 1.0, + "total_count": 1.0, + "0_share": 0.0, + "1_share": 0.0, + "2_share": 0.0, + "3_share": 1.0, + "reference": [{ "numberIntersecting": 4 }] + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-99.0934675895399, 19.4222204725853], + [-99.0934675895399, 19.4220188041236], + [-99.0933535431433, 19.4220188041236], + [-99.0933535431433, 19.4222204725853], + [-99.0934675895399, 19.4222204725853] + ] + ] + ] + } + } + ] +} diff --git a/tests/projects/conflation/features.geojson b/tests/projects/conflation/features.geojson index 1335fe3..ba33346 100644 --- a/tests/projects/conflation/features.geojson +++ b/tests/projects/conflation/features.geojson @@ -1 +1,69 @@ -{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09607039754393,19.42606297126916],[-99.09607039754393,19.42583707815382],[-99.09587079004991,19.42583707815382],[-99.09587079004991,19.42606297126916],[-99.09607039754393,19.42606297126916]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.096234519261,19.42567393293139],[-99.096234519261,19.42543967283784],[-99.09605709037753,19.42543967283784],[-99.09605709037753,19.42567393293139],[-99.096234519261,19.42567393293139]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09455578224427,19.42536198674972],[-99.09455578224427,19.42495865737405],[-99.09425641045227,19.42495865737405],[-99.09425641045227,19.42536198674972],[-99.09455578224427,19.42536198674972]]],"type":"Polygon"}},{"type":"Feature","properties":{},"geometry":{"coordinates":[[[-99.09346758953988,19.42222047258528],[-99.09346758953988,19.422018804123567],[-99.09335354314331,19.422018804123567],[-99.09335354314331,19.42222047258528],[-99.09346758953988,19.42222047258528]]],"type":"Polygon"}}]} \ No newline at end of file +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-99.09607039754393, 19.42606297126916], + [-99.09607039754393, 19.42583707815382], + [-99.09587079004991, 19.42583707815382], + [-99.09587079004991, 19.42606297126916], + [-99.09607039754393, 19.42606297126916] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-99.096234519261, 19.42567393293139], + [-99.096234519261, 19.42543967283784], + [-99.09605709037753, 19.42543967283784], + [-99.09605709037753, 19.42567393293139], + [-99.096234519261, 19.42567393293139] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-99.09455578224427, 19.42536198674972], + [-99.09455578224427, 19.42495865737405], + [-99.09425641045227, 19.42495865737405], + [-99.09425641045227, 19.42536198674972], + [-99.09455578224427, 19.42536198674972] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-99.09346758953988, 19.42222047258528], + [-99.09346758953988, 19.422018804123567], + [-99.09335354314331, 19.422018804123567], + [-99.09335354314331, 19.42222047258528], + [-99.09346758953988, 19.42222047258528] + ] + ], + "type": "Polygon" + } + } + ] +} diff --git a/tests/projects/conflation/project_data.json5 b/tests/projects/conflation/project_data.json5 index e21a15e..89325af 100644 --- a/tests/projects/conflation/project_data.json5 +++ b/tests/projects/conflation/project_data.json5 @@ -99,7 +99,7 @@ projectTypeSpecifics: { conflation: { objectSource: { - objectGeojsonUrl: 'https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f', + objectGeojsonUrl: 'https://drive.google.com/uc?export=download&id=10e50MsbO8BdKVwsjRFmoQQzharX_Am2f', }, tileServerProperty: { name: 'BING', @@ -132,17 +132,17 @@ { blockNumber: 1, blockType: 'text', - textDescription: 'It might look something like this as well' + textDescription: 'It might look something like this as well', }, { blockNumber: 2, blockType: 'text', - textDescription: 'It might look something like this as well' - } + textDescription: 'It might look something like this as well', + }, ], pageNumber: 1, - title: 'Compare building footprints' - } + title: 'Compare building footprints', + }, ], inputGeometries: '', lookFor: 'building', @@ -157,26 +157,26 @@ hint: { description: 'Click Yes', icon: 'help-outline', - title: 'This building looks correct' + title: 'This building looks correct', }, instructions: { description: 'This building looks correct', icon: 'close-outline', - title: 'Correct building' + title: 'Correct building', }, success: { description: 'This building is correct', icon: 'checkmark-outline', - title: 'Well done' - } - } + title: 'Well done', + }, + }, ], status: 'tutorial', tileServer: { apiKey: 'dummy-bing', credits: '© 2019 Microsoft Corporation, Earthstar Geographics SIO', name: 'bing', - url: 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}' + url: 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}', }, tutorialDraftId: '', zoomLevel: 18, @@ -221,115 +221,115 @@ // Expected project expected_project_data: { contributorCount: 0, - created: "2026-01-21T13:49:30.764081+00:00", - createdBy: "01K6CPB1ETTF7MT9EAAQDQM4A9", + created: '2026-01-21T13:49:30.764081+00:00', + createdBy: '01K6CPB1ETTF7MT9EAAQDQM4A9', groupMaxSize: 25, groupSize: 25, isFeatured: false, - language: "en-us", - lookFor: "building", - manualUrl: "https://fair.hotosm.org", + language: 'en-us', + lookFor: 'building', + manualUrl: 'https://fair.hotosm.org', maxTasksPerUser: 30, - name: "Conflate Features - fAIr - Manbhawan (2) Togglecorp", + name: 'Conflate Features - fAIr - Manbhawan (2) Togglecorp', progress: 0, - projectDetails: "This is a conflation project with an extended description", - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - projectInstruction: "Compare buildings", + projectDetails: 'This is a conflation project with an extended description', + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + projectInstruction: 'Compare buildings', projectNumber: 2, - projectRegion: "Manbhawan", - projectTopic: "fAIr", - projectTopicKey: "conflate features - fair - manbhawan (2) togglecorp", + projectRegion: 'Manbhawan', + projectTopic: 'fAIr', + projectTopicKey: 'conflate features - fair - manbhawan (2) togglecorp', projectType: 8, - requestingOrganisation: "Togglecorp", + requestingOrganisation: 'Togglecorp', requiredResults: 12, resultCount: 0, - status: "active", + status: 'active', tileServer: { - apiKey: "dummy-bing", - credits: "© 2019 Microsoft Corporation, Earthstar Geographics SIO", - name: "bing", - url: "https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}" + apiKey: 'dummy-bing', + credits: '© 2019 Microsoft Corporation, Earthstar Geographics SIO', + name: 'bing', + url: 'https://ecn.t0.tiles.virtualearth.net/tiles/a{quad_key}.jpeg?g=15384&mkt=en-US&token={apiKey}', }, - tutorialId: "tutorial_01K4MQ88R61EDAMS0K0TW0N17A", - verificationNumber: 3 + tutorialId: 'tutorial_01K4MQ88R61EDAMS0K0TW0N17A', + verificationNumber: 3, }, expected_project_groups_data: { g100: { finishedCount: 0, - groupId: "g100", + groupId: 'g100', numberOfTasks: 4, progress: 0, - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - requiredCount: 3 - } + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + requiredCount: 3, + }, }, expected_project_tasks_data: { g100: [ { - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - taskId: "t1", + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + taskId: 't1', geojson: { - type: "Polygon", + type: 'Polygon', coordinates: [ [ [-99.0960703975439, 19.4260629712692], [-99.0960703975439, 19.4258370781538], [-99.0958707900499, 19.4258370781538], [-99.0958707900499, 19.4260629712692], - [-99.0960703975439, 19.4260629712692] - ] - ] - } + [-99.0960703975439, 19.4260629712692], + ], + ], + }, }, { - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - taskId: "t2", + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + taskId: 't2', geojson: { - type: "Polygon", + type: 'Polygon', coordinates: [ [ [-99.096234519261, 19.4256739329314], [-99.096234519261, 19.4254396728378], [-99.0960570903775, 19.4254396728378], [-99.0960570903775, 19.4256739329314], - [-99.096234519261, 19.4256739329314] - ] - ] - } + [-99.096234519261, 19.4256739329314], + ], + ], + }, }, { - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - taskId: "t3", + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + taskId: 't3', geojson: { - type: "Polygon", + type: 'Polygon', coordinates: [ [ [-99.0945557822443, 19.4253619867497], [-99.0945557822443, 19.424958657374], [-99.0942564104523, 19.424958657374], [-99.0942564104523, 19.4253619867497], - [-99.0945557822443, 19.4253619867497] - ] - ] - } + [-99.0945557822443, 19.4253619867497], + ], + ], + }, }, { - projectId: "01K339HAWZCTCBRVQMQFWRTHXX", - taskId: "t4", + projectId: '01K339HAWZCTCBRVQMQFWRTHXX', + taskId: 't4', geojson: { - type: "Polygon", + type: 'Polygon', coordinates: [ [ [-99.0934675895399, 19.4222204725853], [-99.0934675895399, 19.4220188041236], [-99.0933535431433, 19.4220188041236], [-99.0933535431433, 19.4222204725853], - [-99.0934675895399, 19.4222204725853] - ] - ] - } - } - ] + [-99.0934675895399, 19.4222204725853], + ], + ], + }, + }, + ], }, // Create contributor group create_contributor_user_group: [ @@ -349,7 +349,7 @@ reference: { t1: { numberIntersecting: 0 }, t2: { numberIntersecting: 0 }, - t3: { + t3: { numberIntersecting: 1, osmId: 1158869168, osmType: 'ways_poly',