diff --git a/.chronus/changes/specs_arm_lro-2024-10-7-15-31-16.md b/.chronus/changes/specs_arm_lro-2024-10-7-15-31-16.md new file mode 100644 index 0000000000..d8940aa0b1 --- /dev/null +++ b/.chronus/changes/specs_arm_lro-2024-10-7-15-31-16.md @@ -0,0 +1,7 @@ +--- +changeKind: feature +packages: + - "@azure-tools/azure-http-specs" +--- + +Added LRO case for ARM tests. \ No newline at end of file diff --git a/packages/azure-http-specs/spec-summary.md b/packages/azure-http-specs/spec-summary.md index 7217ff19aa..4e3523f47c 100644 --- a/packages/azure-http-specs/spec-summary.md +++ b/packages/azure-http-specs/spec-summary.md @@ -916,6 +916,218 @@ Expected response body: } ``` +### Azure_ResourceManager_OperationTemplates_Lro_createOrReplace + +- Endpoint: `put https://management.azure.com` + +Resource PUT operation. +Service returns "Azure-AsyncOperation" on initial request. +final-state-via: Azure-AsyncOperation + +Expected verb: PUT +Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 +Expected query parameter: api-version=2023-12-01-preview +Expected request body: + +```json +{ + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1 + } +} +``` + +Expected status code: 201 +Expected response header: Azure-AsyncOperation={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1", + "name": "order1", + "type": "Azure.ResourceManager.Resources/orders", + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1, + "provisioningState": "InProgress" + }, + "systemData": { + "createdBy": "AzureSDK", + "createdByType": "User", + "createdAt": , + "lastModifiedBy": "AzureSDK", + "lastModifiedAt": , + "lastModifiedByType": "User", + } +} +``` + +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao + +Expected status code: 200 +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao", + "name": "lro_create_aao", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "status": "InProgress" +} +``` + +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao + +Expected status code: 200 +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao", + "name": "lro_create_aao", + "status": "Succeeded", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "endTime": "2024-11-08T01:42:41.5354192+00:00" +} +``` + +Last get call on resource URL +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 + +Expected status code: 200 +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1", + "name": "order1", + "type": "Azure.ResourceManager.Resources/orders", + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1, + "provisioningState": "Succeeded" + }, + "systemData": { + "createdBy": "AzureSDK", + "createdByType": "User", + "createdAt": , + "lastModifiedBy": "AzureSDK", + "lastModifiedAt": , + "lastModifiedByType": "User", + } +} +``` + +### Azure_ResourceManager_OperationTemplates_Lro_delete + +- Endpoint: `delete https://management.azure.com` + +Resource DELETE operation. +Service returns both Location header on initial request. + +Expected verb: DELETE +Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 +Expected query parameter: api-version=2023-12-01-preview +Expected response status code: 202 +Expected response header: Location={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location +Expected no response body + +Location first poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location +Expected status code: 202 +Expected no response body + +Location second poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location +Expected status code: 204 +Expected no response body + +### Azure_ResourceManager_OperationTemplates_Lro_export + +- Endpoint: `post https://management.azure.com` + +Resource POST operation. +Service returns both Location and Azure-AsyncOperation header on initial request. +final-state-via: location + +Expected verb: POST +Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1/export +Expected query parameter: api-version=2023-12-01-preview +Expected request body: + +```json +{ + "format": "csv" +} +``` + +Expected response status code: 202 +Expected response headers: + +- Azure-AsyncOperation={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao +- Location={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/operations/lro_post_location + Expected no response body + +Whether you do polling through AAO, Location or combined, first one will respond with provisioning state "InProgress", second one with "Succeeded". + +AAO first poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao +Expected status code: 200 +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao", + "name": "lro_post_aao", + "status": "InProgress", + "startTime": "2024-11-08T01:41:53.5508583+00:00" +} +``` + +AAO second poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao +Expected status code: 200 +Expected response body: + +```json +{ + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao", + "name": "lro_post_aao", + "status": "Succeeded", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "endTime": "2024-11-08T01:42:41.5354192+00:00" +} +``` + +Location first poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location +Expected status code: 202 +Expected no response body + +Location second poll. +Expected verb: GET +Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location +Expected status code: 200 +Expected response body: + +```json +{ + "content": "order1,product1,1" +} +``` + ### Azure_ResourceManager_Resources_Nested_createOrReplace - Endpoint: `put https://management.azure.com` diff --git a/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/lro.tsp b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/lro.tsp new file mode 100644 index 0000000000..3fd7f9f9a9 --- /dev/null +++ b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/lro.tsp @@ -0,0 +1,249 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@azure-tools/typespec-azure-core"; +import "@azure-tools/typespec-azure-resource-manager"; +import "@typespec/spector"; + +using TypeSpec.Http; +using TypeSpec.Rest; +using Azure.Core; +using Azure.ResourceManager; +using TypeSpec.OpenAPI; +using Spector; + +namespace Azure.ResourceManager.OperationTemplates; + +@resource("orders") +model Order is TrackedResource { + ...ResourceNameParameter; +} + +model OrderProperties { + @doc("The product ID of the order.") + productId: string; + + @doc("Amount of the product.") + amount: int32; + + @doc("The provisioning state of the product.") + @visibility("read") + provisioningState?: string; +} + +model ExportRequest { + @doc("Format of the exported order.") + format: string; +} + +model ExportResult { + @doc("Content of the exported order.") + content: string; +} + +@armResourceOperations +interface Lro { + @scenario + @scenarioDoc(""" + Resource PUT operation. + Service returns "Azure-AsyncOperation" on initial request. + final-state-via: Azure-AsyncOperation + + Expected verb: PUT + Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 + Expected query parameter: api-version=2023-12-01-preview + Expected request body: + ```json + { + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1 + } + } + ``` + Expected status code: 201 + Expected response header: Azure-AsyncOperation={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1", + "name": "order1", + "type": "Azure.ResourceManager.Resources/orders", + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1, + "provisioningState": "InProgress" + }, + "systemData": { + "createdBy": "AzureSDK", + "createdByType": "User", + "createdAt": , + "lastModifiedBy": "AzureSDK", + "lastModifiedAt": , + "lastModifiedByType": "User", + } + } + ``` + + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao + + Expected status code: 200 + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao", + "name": "lro_create_aao", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "status" : "InProgress" + } + ``` + + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao + + Expected status code: 200 + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao", + "name": "lro_create_aao", + "status" : "Succeeded", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "endTime": "2024-11-08T01:42:41.5354192+00:00" + } + ``` + + Last get call on resource URL + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 + + Expected status code: 200 + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1", + "name": "order1", + "type": "Azure.ResourceManager.Resources/orders", + "location": "eastus", + "properties": { + "productId": "product1", + "amount": 1, + "provisioningState": "Succeeded" + }, + "systemData": { + "createdBy": "AzureSDK", + "createdByType": "User", + "createdAt": , + "lastModifiedBy": "AzureSDK", + "lastModifiedAt": , + "lastModifiedByType": "User", + } + } + ``` + """) + createOrReplace is ArmResourceCreateOrReplaceAsync; + + @scenario + @scenarioDoc(""" + Resource POST operation. + Service returns both Location and Azure-AsyncOperation header on initial request. + final-state-via: location + + Expected verb: POST + Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1/export + Expected query parameter: api-version=2023-12-01-preview + Expected request body: + ```json + { + "format": "csv" + } + ``` + Expected response status code: 202 + Expected response headers: + - Azure-AsyncOperation={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao + - Location={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/operations/lro_post_location + Expected no response body + + Whether you do polling through AAO, Location or combined, first one will respond with provisioning state "InProgress", second one with "Succeeded". + + AAO first poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao + Expected status code: 200 + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao", + "name": "lro_post_aao", + "status" : "InProgress", + "startTime": "2024-11-08T01:41:53.5508583+00:00" + } + ``` + + AAO second poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao + Expected status code: 200 + Expected response body: + ```json + { + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao", + "name": "lro_post_aao", + "status" : "Succeeded", + "startTime": "2024-11-08T01:41:53.5508583+00:00", + "endTime": "2024-11-08T01:42:41.5354192+00:00" + } + ``` + + Location first poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location + Expected status code: 202 + Expected no response body + + Location second poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location + Expected status code: 200 + Expected response body: + ```json + { + "content": "order1,product1,1" + } + ``` + """) + export is ArmResourceActionAsync< + Order, + ExportRequest, + ExportResult, + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader + >; + + @scenario + @scenarioDoc(""" + Resource DELETE operation. + Service returns both Location header on initial request. + + Expected verb: DELETE + Expected path: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Azure.ResourceManager.OperationTemplates/orders/order1 + Expected query parameter: api-version=2023-12-01-preview + Expected response status code: 202 + Expected response header: Location={endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location + Expected no response body + + Location first poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location + Expected status code: 202 + Expected no response body + + Location second poll. + Expected verb: GET + Expected URL: {endpoint}/subscriptions/00000000-0000-0000-0000-000000000000/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location + Expected status code: 204 + Expected no response body + """) + delete is ArmResourceDeleteWithoutOkAsync; +} diff --git a/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/main.tsp b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/main.tsp new file mode 100644 index 0000000000..c5073e69d1 --- /dev/null +++ b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/main.tsp @@ -0,0 +1,29 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@typespec/versioning"; +import "@azure-tools/typespec-azure-core"; +import "@azure-tools/typespec-azure-resource-manager"; +import "@azure-tools/typespec-client-generator-core"; +import "./lro.tsp"; + +using TypeSpec.Http; +using TypeSpec.Rest; +using TypeSpec.Versioning; +using Azure.Core; +using Azure.ResourceManager; +using TypeSpec.OpenAPI; + +@armProviderNamespace +@service +@versioned(Versions) +@doc("Arm Resource Provider management API.") +namespace Azure.ResourceManager.OperationTemplates; + +@doc("Azure API versions.") +enum Versions { + @armCommonTypesVersion(CommonTypes.Versions.v5) + @useDependency(Azure.Core.Versions.v1_0_Preview_2) + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + @doc("Preview API version 2023-12-01-preview.") + v2023_12_01_preview: "2023-12-01-preview", +} diff --git a/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/mockapi.ts b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/mockapi.ts new file mode 100644 index 0000000000..a442f08578 --- /dev/null +++ b/packages/azure-http-specs/specs/azure/resource-manager/operation-templates/mockapi.ts @@ -0,0 +1,302 @@ +import { + json, + MockRequest, + passOnSuccess, + ScenarioMockApi, + ValidationError, +} from "@typespec/spec-api"; + +export const Scenarios: Record = {}; + +const SUBSCRIPTION_ID_EXPECTED = "00000000-0000-0000-0000-000000000000"; +const RESOURCE_GROUP_EXPECTED = "test-rg"; +const validOrder = { + id: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/resourceGroups/${RESOURCE_GROUP_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/orders/order1`, + name: "order1", + type: "Azure.ResourceManager.Resources/orders", + location: "eastus", + properties: { + provisioningState: "Succeeded", + productId: "product1", + amount: 1, + }, + systemData: { + createdBy: "AzureSDK", + createdByType: "User", + createdAt: "2024-10-04T00:56:07.442Z", + lastModifiedBy: "AzureSDK", + lastModifiedAt: "2024-10-04T00:56:07.442Z", + lastModifiedByType: "User", + }, +}; +let createOrReplacePollCount = 0; +let postPollCount = 0; +let deletePollCount = 0; + +// lro resource +Scenarios.Azure_ResourceManager_OperationTemplates_Lro_createOrReplace = passOnSuccess([ + { + // LRO PUT initial request + uri: "/subscriptions/:subscriptionId/resourceGroups/:resourceGroup/providers/Azure.ResourceManager.OperationTemplates/orders/:orderName", + method: "put", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + resourceGroup: RESOURCE_GROUP_EXPECTED, + orderName: "order1", + "api-version": "2023-12-01-preview", + }, + body: { + location: "eastus", + properties: { + productId: "product1", + amount: 1, + }, + }, + }, + response: { + status: 201, + headers: { + "azure-asyncoperation": `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao`, + }, + body: json({ + ...validOrder, + properties: { + provisioningState: "InProgress", + }, + }), + }, + handler: (req: MockRequest) => { + createOrReplacePollCount = 0; + return { + status: 201, + headers: { + "azure-asyncoperation": `${req.baseUrl}/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao`, + }, + body: json({ + ...validOrder, + properties: { + provisioningState: "InProgress", + }, + }), + }; + }, + kind: "MockApiDefinition", + }, + { + // LRO PUT poll intermediate/get final result + uri: "/subscriptions/:subscriptionId/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao", + method: "get", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + "api-version": "2023-12-01-preview", + }, + }, + response: { + status: 202, + body: json({ + id: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao`, + name: "lro_create_aao", + startTime: "2024-11-08T01:41:53.5508583+00:00", + status: "InProgress", + }), + }, + handler: (req: MockRequest) => { + const aaoResponse = { + id: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_create_aao`, + name: "lro_create_aao", + startTime: "2024-11-08T01:41:53.5508583+00:00", + }; + const response = + createOrReplacePollCount > 0 + ? { + ...aaoResponse, + status: "Succeeded", + endTime: "2024-11-08T01:42:41.5354192+00:00", + properties: validOrder, + } + : { ...aaoResponse, status: "InProgress" }; + const statusCode = createOrReplacePollCount > 0 ? 200 : 202; + createOrReplacePollCount += 1; + return { + status: statusCode, + body: json(response), + }; + }, + kind: "MockApiDefinition", + }, + { + // LRO PUT get final result through initial request uri + uri: "/subscriptions/:subscriptionId/resourceGroups/:resourceGroup/providers/Azure.ResourceManager.OperationTemplates/orders/:orderName", + method: "get", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + resourceGroup: RESOURCE_GROUP_EXPECTED, + orderName: "order1", + "api-version": "2023-12-01-preview", + }, + }, + response: { + status: 200, + body: json(validOrder), + }, + kind: "MockApiDefinition", + }, +]); + +Scenarios.Azure_ResourceManager_OperationTemplates_Lro_export = passOnSuccess([ + { + // LRO POST initial request + uri: "/subscriptions/:subscriptionId/resourceGroups/:resourceGroup/providers/Azure.ResourceManager.OperationTemplates/orders/:orderName/export", + method: "post", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + resourceGroup: RESOURCE_GROUP_EXPECTED, + orderName: "order1", + "api-version": "2023-12-01-preview", + }, + body: { + format: "csv", + }, + }, + response: { + status: 202, + headers: { + location: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location`, + "azure-asyncoperation": `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao`, + }, + }, + handler: (req: MockRequest) => { + postPollCount = 0; + return { + status: 202, + headers: { + location: `${req.baseUrl}/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_location`, + "azure-asyncoperation": `${req.baseUrl}/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao`, + }, + }; + }, + kind: "MockApiDefinition", + }, + { + // LRO POST poll intermediate/get final result + uri: "/subscriptions/:subscriptionId/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/:operation_name", + method: "get", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + "api-version": "2023-12-01-preview", + operation_name: "lro_post_aao", // operation_name can be "lro_post_location" or "lro_post_aao", depending on the header you choose to poll. "lro_post_aao" here is just for passing e2e test + }, + }, + response: { + status: 200, // This is for passing e2e test. For actual status code, see "handler" definition below + }, + handler: (req: MockRequest) => { + let response; + const operation_name = req.params["operation_name"]; + if (operation_name === "lro_post_location") { + response = + // first status will be 200, second and forward be 204 + postPollCount > 0 + ? { + status: 200, + body: json({ + content: "order1,product1,1", + }), + } + : { status: 202 }; + } else if (operation_name === "lro_post_aao") { + const aaoResponse = { + id: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operations/lro_post_aao`, + name: "lro_post_aao", + startTime: "2024-11-08T01:41:53.5508583+00:00", + }; + // first provisioningState will be "InProgress", second and forward be "Succeeded" + const responseBody = + postPollCount > 0 + ? { + ...aaoResponse, + status: "Succeeded", + endTime: "2024-11-08T01:42:41.5354192+00:00", + } + : { ...aaoResponse, status: "InProgress" }; + + response = { + status: 200, // aao always returns 200 with response body + body: json(responseBody), + }; + } else { + throw new ValidationError( + `Unexpected lro poll operation: ${operation_name}`, + undefined, + undefined, + ); + } + + postPollCount += 1; + + return response; + }, + kind: "MockApiDefinition", + }, +]); + +Scenarios.Azure_ResourceManager_OperationTemplates_Lro_delete = passOnSuccess([ + { + // LRO DELETE initial request + uri: "/subscriptions/:subscriptionId/resourceGroups/:resourceGroup/providers/Azure.ResourceManager.OperationTemplates/orders/:orderName", + method: "delete", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + resourceGroup: RESOURCE_GROUP_EXPECTED, + orderName: "order1", + "api-version": "2023-12-01-preview", + }, + }, + response: { + status: 202, + headers: { + location: `/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location`, + }, + }, + handler: (req: MockRequest) => { + deletePollCount = 0; + return { + status: 202, + headers: { + location: `${req.baseUrl}/subscriptions/${SUBSCRIPTION_ID_EXPECTED}/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location`, + }, + }; + }, + kind: "MockApiDefinition", + }, + { + // LRO DELETE poll intermediate/get final result + uri: "/subscriptions/:subscriptionId/providers/Azure.ResourceManager.OperationTemplates/locations/eastus/operationResults/lro_delete_location", + method: "get", + request: { + params: { + subscriptionId: SUBSCRIPTION_ID_EXPECTED, + "api-version": "2023-12-01-preview", + }, + }, + response: { + status: 202, // This is for passing e2e test. For actual status code, see "handler" definition below + }, + handler: (req: MockRequest) => { + const response = + // first status will be 202, second and forward be 204 + deletePollCount > 0 ? { status: 204 } : { status: 202 }; + + deletePollCount += 1; + + return response; + }, + kind: "MockApiDefinition", + }, +]);