# This file is auto-generated by oagen. Do not edit.

import json

import pytest
from workos import WorkOSClient, AsyncWorkOSClient
from tests.generated_helpers import load_fixture

from workos.common.models import ConnectApplicationOAuth, PaginationOrder
from workos.connect.models import (
    ApplicationCredentialsListItem,
    ExternalAuthCompleteResponse,
    NewConnectApplicationSecret,
    UserObject,
)
from workos._pagination import AsyncPage, SyncPage
from workos._errors import (
    AuthenticationError,
    BadRequestError,
    NotFoundError,
    RateLimitExceededError,
    ServerError,
    UnprocessableEntityError,
)


class TestConnect:
    def test_complete_oauth2(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("external_auth_complete_response.json"),
        )
        result = workos.connect.complete_oauth2(
            external_auth_id="test_external_auth_id",
            user=UserObject.from_dict(load_fixture("user_object.json")),
        )
        assert isinstance(result, ExternalAuthCompleteResponse)
        assert (
            result.redirect_uri
            == "https://your-authkit-domain.workos.com/oauth/authorize/complete?state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0ZSI6InJhbmRvbV9zdGF0ZV9zdHJpbmciLCJpYXQiOjE3NDI2MDQ4NTN9.abc123def456ghi789"
        )
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/authkit/oauth2/complete")
        body = json.loads(request.content)
        assert body["external_auth_id"] == "test_external_auth_id"
        assert "user" in body

    def test_list_applications(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("list_connect_application.json"),
        )
        page = workos.connect.list_applications()
        assert isinstance(page, SyncPage)
        assert len(page.data) == 1
        assert isinstance(page.data[0], ConnectApplicationOAuth)

    def test_list_applications_empty_page(self, workos, httpx_mock):
        httpx_mock.add_response(json={"data": [], "list_metadata": {}})
        page = workos.connect.list_applications()
        assert isinstance(page, SyncPage)
        assert page.data == []

    def test_list_applications_encodes_query_params(self, workos, httpx_mock):
        httpx_mock.add_response(json={"data": [], "list_metadata": {}})
        workos.connect.list_applications(
            limit=10,
            before="cursor before",
            after="cursor/after",
            order=PaginationOrder("value_order"),
            registration_types=["val1", "val2"],
            organization_id="value organization_id/test",
        )
        request = httpx_mock.get_request()
        assert request.url.params["limit"] == "10"
        assert request.url.params["before"] == "cursor before"
        assert request.url.params["after"] == "cursor/after"
        assert request.url.params["order"] == "value_order"
        assert request.url.params["registration_types"] == "val1,val2"
        assert request.url.params["organization_id"] == "value organization_id/test"

    def test_create_application(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("connect_application.json"),
        )
        result = workos.connect.create_application(
            body=load_fixture("create_oauth_application.json")
        )
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/connect/applications")

    def test_get_application(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("connect_application.json"),
        )
        result = workos.connect.get_application("test_id")
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "GET"
        assert request.url.path.endswith("/connect/applications/test_id")

    def test_update_application(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("connect_application.json"),
        )
        result = workos.connect.update_application("test_id")
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "PUT"
        assert request.url.path.endswith("/connect/applications/test_id")

    def test_delete_application(self, workos, httpx_mock):
        httpx_mock.add_response(status_code=204)
        result = workos.connect.delete_application("test_id")
        assert result is None
        request = httpx_mock.get_request()
        assert request.method == "DELETE"
        assert request.url.path.endswith("/connect/applications/test_id")

    def test_list_application_client_secrets(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=[load_fixture("application_credentials_list_item.json")]
        )
        result = workos.connect.list_application_client_secrets("test_id")
        assert isinstance(result, list)
        assert len(result) == 1
        assert isinstance(result[0], ApplicationCredentialsListItem)

    def test_create_application_client_secret(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("new_connect_application_secret.json"),
        )
        result = workos.connect.create_application_client_secret("test_id")
        assert isinstance(result, NewConnectApplicationSecret)
        assert result.object == "connect_application_secret"
        assert result.id == "secret_01J9Q2Z3X4Y5W6V7U8T9S0R1Q"
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/connect/applications/test_id/client_secrets")

    def test_delete_client_secret(self, workos, httpx_mock):
        httpx_mock.add_response(status_code=204)
        result = workos.connect.delete_client_secret("test_id")
        assert result is None
        request = httpx_mock.get_request()
        assert request.method == "DELETE"
        assert request.url.path.endswith("/connect/client_secrets/test_id")

    def test_create_oauth_application(self, workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = workos.connect.create_oauth_application(
            name="test_name", is_first_party=True
        )
        assert isinstance(result, ConnectApplicationOAuth)
        request = httpx_mock.get_request()
        assert request.method == "POST"
        body = json.loads(request.content)
        assert body["application_type"] == "oauth"

    def test_create_m2m_application(self, workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = workos.connect.create_m2m_application(
            name="test_name", organization_id="test_organization_id"
        )
        assert isinstance(result, ConnectApplicationOAuth)
        request = httpx_mock.get_request()
        assert request.method == "POST"
        body = json.loads(request.content)
        assert body["application_type"] == "m2m"

    def test_complete_oauth2_with_request_options(self, workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("external_auth_complete_response.json")
        )
        workos.connect.complete_oauth2(
            external_auth_id="test_external_auth_id",
            user=UserObject.from_dict(load_fixture("user_object.json")),
            request_options={"extra_headers": {"X-Custom": "value"}},
        )
        request = httpx_mock.get_request()
        assert request.headers["X-Custom"] == "value"

    def test_complete_oauth2_unauthorized(self, workos, httpx_mock):
        httpx_mock.add_response(
            status_code=401,
            json={"message": "Unauthorized"},
        )
        with pytest.raises(AuthenticationError):
            workos.connect.complete_oauth2(
                external_auth_id="test_external_auth_id",
                user=UserObject.from_dict(load_fixture("user_object.json")),
            )

    def test_complete_oauth2_not_found(self, httpx_mock):
        workos = WorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=404, json={"message": "Not found"})
            with pytest.raises(NotFoundError):
                workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            workos.close()

    def test_complete_oauth2_rate_limited(self, httpx_mock):
        workos = WorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(
                status_code=429,
                headers={"Retry-After": "0"},
                json={"message": "Slow down"},
            )
            with pytest.raises(RateLimitExceededError):
                workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            workos.close()

    def test_complete_oauth2_server_error(self, httpx_mock):
        workos = WorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=500, json={"message": "Server error"})
            with pytest.raises(ServerError):
                workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            workos.close()

    def test_complete_oauth2_bad_request(self, httpx_mock):
        workos = WorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=400, json={"message": "Bad request"})
            with pytest.raises(BadRequestError):
                workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            workos.close()

    def test_complete_oauth2_unprocessable(self, httpx_mock):
        workos = WorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=422, json={"message": "Unprocessable"})
            with pytest.raises(UnprocessableEntityError):
                workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            workos.close()


class TestAsyncConnect:
    @pytest.mark.asyncio
    async def test_complete_oauth2(self, async_workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("external_auth_complete_response.json")
        )
        result = await async_workos.connect.complete_oauth2(
            external_auth_id="test_external_auth_id",
            user=UserObject.from_dict(load_fixture("user_object.json")),
        )
        assert isinstance(result, ExternalAuthCompleteResponse)
        assert (
            result.redirect_uri
            == "https://your-authkit-domain.workos.com/oauth/authorize/complete?state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0ZSI6InJhbmRvbV9zdGF0ZV9zdHJpbmciLCJpYXQiOjE3NDI2MDQ4NTN9.abc123def456ghi789"
        )
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/authkit/oauth2/complete")

    @pytest.mark.asyncio
    async def test_list_applications(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("list_connect_application.json"))
        page = await async_workos.connect.list_applications()
        assert isinstance(page, AsyncPage)
        assert len(page.data) == 1
        assert isinstance(page.data[0], ConnectApplicationOAuth)

    @pytest.mark.asyncio
    async def test_list_applications_empty_page(self, async_workos, httpx_mock):
        httpx_mock.add_response(json={"data": [], "list_metadata": {}})
        page = await async_workos.connect.list_applications()
        assert isinstance(page, AsyncPage)
        assert page.data == []

    @pytest.mark.asyncio
    async def test_list_applications_encodes_query_params(
        self, async_workos, httpx_mock
    ):
        httpx_mock.add_response(json={"data": [], "list_metadata": {}})
        await async_workos.connect.list_applications(
            limit=10,
            before="cursor before",
            after="cursor/after",
            order=PaginationOrder("value_order"),
            registration_types=["val1", "val2"],
            organization_id="value organization_id/test",
        )
        request = httpx_mock.get_request()
        assert request.url.params["limit"] == "10"
        assert request.url.params["before"] == "cursor before"
        assert request.url.params["after"] == "cursor/after"
        assert request.url.params["order"] == "value_order"
        assert request.url.params["registration_types"] == "val1,val2"
        assert request.url.params["organization_id"] == "value organization_id/test"

    @pytest.mark.asyncio
    async def test_create_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = await async_workos.connect.create_application(
            body=load_fixture("create_oauth_application.json")
        )
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/connect/applications")

    @pytest.mark.asyncio
    async def test_get_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = await async_workos.connect.get_application("test_id")
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "GET"
        assert request.url.path.endswith("/connect/applications/test_id")

    @pytest.mark.asyncio
    async def test_update_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = await async_workos.connect.update_application("test_id")
        assert isinstance(result, ConnectApplicationOAuth)
        assert result.object == "connect_application"
        assert result.id == "conn_app_01HXYZ123456789ABCDEFGHIJ"
        request = httpx_mock.get_request()
        assert request.method == "PUT"
        assert request.url.path.endswith("/connect/applications/test_id")

    @pytest.mark.asyncio
    async def test_delete_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(status_code=204)
        result = await async_workos.connect.delete_application("test_id")
        assert result is None
        request = httpx_mock.get_request()
        assert request.method == "DELETE"
        assert request.url.path.endswith("/connect/applications/test_id")

    @pytest.mark.asyncio
    async def test_list_application_client_secrets(self, async_workos, httpx_mock):
        httpx_mock.add_response(
            json=[load_fixture("application_credentials_list_item.json")]
        )
        result = await async_workos.connect.list_application_client_secrets("test_id")
        assert isinstance(result, list)
        assert len(result) == 1
        assert isinstance(result[0], ApplicationCredentialsListItem)

    @pytest.mark.asyncio
    async def test_create_application_client_secret(self, async_workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("new_connect_application_secret.json")
        )
        result = await async_workos.connect.create_application_client_secret("test_id")
        assert isinstance(result, NewConnectApplicationSecret)
        assert result.object == "connect_application_secret"
        assert result.id == "secret_01J9Q2Z3X4Y5W6V7U8T9S0R1Q"
        request = httpx_mock.get_request()
        assert request.method == "POST"
        assert request.url.path.endswith("/connect/applications/test_id/client_secrets")

    @pytest.mark.asyncio
    async def test_delete_client_secret(self, async_workos, httpx_mock):
        httpx_mock.add_response(status_code=204)
        result = await async_workos.connect.delete_client_secret("test_id")
        assert result is None
        request = httpx_mock.get_request()
        assert request.method == "DELETE"
        assert request.url.path.endswith("/connect/client_secrets/test_id")

    @pytest.mark.asyncio
    async def test_create_oauth_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = await async_workos.connect.create_oauth_application(
            name="test_name", is_first_party=True
        )
        assert isinstance(result, ConnectApplicationOAuth)
        request = httpx_mock.get_request()
        assert request.method == "POST"
        body = json.loads(request.content)
        assert body["application_type"] == "oauth"

    @pytest.mark.asyncio
    async def test_create_m2m_application(self, async_workos, httpx_mock):
        httpx_mock.add_response(json=load_fixture("connect_application.json"))
        result = await async_workos.connect.create_m2m_application(
            name="test_name", organization_id="test_organization_id"
        )
        assert isinstance(result, ConnectApplicationOAuth)
        request = httpx_mock.get_request()
        assert request.method == "POST"
        body = json.loads(request.content)
        assert body["application_type"] == "m2m"

    @pytest.mark.asyncio
    async def test_complete_oauth2_with_request_options(self, async_workos, httpx_mock):
        httpx_mock.add_response(
            json=load_fixture("external_auth_complete_response.json")
        )
        await async_workos.connect.complete_oauth2(
            external_auth_id="test_external_auth_id",
            user=UserObject.from_dict(load_fixture("user_object.json")),
            request_options={"extra_headers": {"X-Custom": "value"}},
        )
        request = httpx_mock.get_request()
        assert request.headers["X-Custom"] == "value"

    @pytest.mark.asyncio
    async def test_complete_oauth2_unauthorized(self, async_workos, httpx_mock):
        httpx_mock.add_response(status_code=401, json={"message": "Unauthorized"})
        with pytest.raises(AuthenticationError):
            await async_workos.connect.complete_oauth2(
                external_auth_id="test_external_auth_id",
                user=UserObject.from_dict(load_fixture("user_object.json")),
            )

    @pytest.mark.asyncio
    async def test_complete_oauth2_not_found(self, httpx_mock):
        workos = AsyncWorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=404, json={"message": "Not found"})
            with pytest.raises(NotFoundError):
                await workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            await workos.close()

    @pytest.mark.asyncio
    async def test_complete_oauth2_rate_limited(self, httpx_mock):
        workos = AsyncWorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(
                status_code=429,
                headers={"Retry-After": "0"},
                json={"message": "Slow down"},
            )
            with pytest.raises(RateLimitExceededError):
                await workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            await workos.close()

    @pytest.mark.asyncio
    async def test_complete_oauth2_server_error(self, httpx_mock):
        workos = AsyncWorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=500, json={"message": "Server error"})
            with pytest.raises(ServerError):
                await workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            await workos.close()

    @pytest.mark.asyncio
    async def test_complete_oauth2_bad_request(self, httpx_mock):
        workos = AsyncWorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=400, json={"message": "Bad request"})
            with pytest.raises(BadRequestError):
                await workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            await workos.close()

    @pytest.mark.asyncio
    async def test_complete_oauth2_unprocessable(self, httpx_mock):
        workos = AsyncWorkOSClient(
            api_key="sk_test_123", client_id="client_test", max_retries=0
        )
        try:
            httpx_mock.add_response(status_code=422, json={"message": "Unprocessable"})
            with pytest.raises(UnprocessableEntityError):
                await workos.connect.complete_oauth2(
                    external_auth_id="test_external_auth_id",
                    user=UserObject.from_dict(load_fixture("user_object.json")),
                )
        finally:
            await workos.close()
