mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	This reimplements our Zoom video call integration to use an OAuth application. In addition to providing a cleaner setup experience, especially on zulipchat.com where the server administrators can have done the app registration already, it also fixes the limitation of the previous integration that it could only have one call active at a time when set up with typical Zoom API keys. Fixes #11672. Co-authored-by: Marco Burstein <marco@marco.how> Co-authored-by: Tim Abbott <tabbott@zulipchat.com> Signed-off-by: Anders Kaseorg <andersk@mit.edu>
		
			
				
	
	
		
			159 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import responses
 | 
						|
from zerver.lib.test_classes import ZulipTestCase
 | 
						|
 | 
						|
 | 
						|
class TestVideoCall(ZulipTestCase):
 | 
						|
    def setUp(self) -> None:
 | 
						|
        super().setUp()
 | 
						|
        self.user = self.example_user("hamlet")
 | 
						|
        self.login_user(self.user)
 | 
						|
 | 
						|
    def test_register_video_request_no_settings(self) -> None:
 | 
						|
        with self.settings(VIDEO_ZOOM_CLIENT_ID=None):
 | 
						|
            response = self.client_get("/calls/zoom/register")
 | 
						|
            self.assert_json_error(
 | 
						|
                response, "Zoom credentials have not been configured"
 | 
						|
            )
 | 
						|
 | 
						|
    def test_register_video_request(self) -> None:
 | 
						|
        response = self.client_get("/calls/zoom/register")
 | 
						|
        self.assertEqual(response.status_code, 302)
 | 
						|
 | 
						|
    @responses.activate
 | 
						|
    def test_create_video_request_success(self) -> None:
 | 
						|
        responses.add(
 | 
						|
            responses.POST,
 | 
						|
            "https://zoom.us/oauth/token",
 | 
						|
            json={"access_token": "oldtoken", "expires_in": -60},
 | 
						|
        )
 | 
						|
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zulip","sid":""}'},
 | 
						|
        )
 | 
						|
        self.assertEqual(response.status_code, 200)
 | 
						|
 | 
						|
        responses.replace(
 | 
						|
            responses.POST,
 | 
						|
            "https://zoom.us/oauth/token",
 | 
						|
            json={"access_token": "newtoken", "expires_in": 60},
 | 
						|
        )
 | 
						|
 | 
						|
        responses.add(
 | 
						|
            responses.POST,
 | 
						|
            "https://api.zoom.us/v2/users/me/meetings",
 | 
						|
            json={"join_url": "example.com"},
 | 
						|
        )
 | 
						|
 | 
						|
        response = self.client_post("/json/calls/zoom/create")
 | 
						|
        self.assertEqual(
 | 
						|
            responses.calls[-1].request.url, "https://api.zoom.us/v2/users/me/meetings"
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            responses.calls[-1].request.headers["Authorization"], "Bearer newtoken"
 | 
						|
        )
 | 
						|
        json = self.assert_json_success(response)
 | 
						|
        self.assertEqual(json["url"], "example.com")
 | 
						|
 | 
						|
        self.logout()
 | 
						|
        self.login_user(self.user)
 | 
						|
 | 
						|
        response = self.client_post("/json/calls/zoom/create")
 | 
						|
        self.assert_json_error(response, "Invalid Zoom access token")
 | 
						|
 | 
						|
    def test_create_video_realm_redirect(self) -> None:
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zephyr","sid":"somesid"}'},
 | 
						|
        )
 | 
						|
        self.assertEqual(response.status_code, 302)
 | 
						|
        self.assertIn("http://zephyr.testserver/", response.url)
 | 
						|
        self.assertIn("somesid", response.url)
 | 
						|
 | 
						|
    def test_create_video_sid_error(self) -> None:
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zulip","sid":"bad"}'},
 | 
						|
        )
 | 
						|
        self.assert_json_error(response, "Invalid Zoom session identifier")
 | 
						|
 | 
						|
    @responses.activate
 | 
						|
    def test_create_video_credential_error(self) -> None:
 | 
						|
        responses.add(responses.POST, "https://zoom.us/oauth/token", status=400)
 | 
						|
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zulip","sid":""}'},
 | 
						|
        )
 | 
						|
        self.assert_json_error(response, "Invalid Zoom credentials")
 | 
						|
 | 
						|
    @responses.activate
 | 
						|
    def test_create_video_refresh_error(self) -> None:
 | 
						|
        responses.add(
 | 
						|
            responses.POST,
 | 
						|
            "https://zoom.us/oauth/token",
 | 
						|
            json={"access_token": "token", "expires_in": -60},
 | 
						|
        )
 | 
						|
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zulip","sid":""}'},
 | 
						|
        )
 | 
						|
        self.assertEqual(response.status_code, 200)
 | 
						|
 | 
						|
        responses.replace(responses.POST, "https://zoom.us/oauth/token", status=400)
 | 
						|
 | 
						|
        response = self.client_post("/json/calls/zoom/create")
 | 
						|
        self.assert_json_error(response, "Invalid Zoom access token")
 | 
						|
 | 
						|
    @responses.activate
 | 
						|
    def test_create_video_request_error(self) -> None:
 | 
						|
        responses.add(
 | 
						|
            responses.POST,
 | 
						|
            "https://zoom.us/oauth/token",
 | 
						|
            json={"access_token": "token"},
 | 
						|
        )
 | 
						|
 | 
						|
        responses.add(
 | 
						|
            responses.POST, "https://api.zoom.us/v2/users/me/meetings", status=400
 | 
						|
        )
 | 
						|
 | 
						|
        response = self.client_get(
 | 
						|
            "/calls/zoom/complete",
 | 
						|
            {"code": "code", "state": '{"realm":"zulip","sid":""}'},
 | 
						|
        )
 | 
						|
        self.assertEqual(response.status_code, 200)
 | 
						|
 | 
						|
        response = self.client_post("/json/calls/zoom/create")
 | 
						|
        self.assert_json_error(response, "Failed to create Zoom call")
 | 
						|
 | 
						|
        responses.replace(
 | 
						|
            responses.POST, "https://api.zoom.us/v2/users/me/meetings", status=401
 | 
						|
        )
 | 
						|
 | 
						|
        response = self.client_post("/json/calls/zoom/create")
 | 
						|
        self.assert_json_error(response, "Invalid Zoom access token")
 | 
						|
 | 
						|
    @responses.activate
 | 
						|
    def test_deauthorize_zoom_user(self) -> None:
 | 
						|
        responses.add(responses.POST, "https://api.zoom.us/oauth/data/compliance")
 | 
						|
 | 
						|
        response = self.client_post(
 | 
						|
            "/calls/zoom/deauthorize",
 | 
						|
            """\
 | 
						|
{
 | 
						|
  "event": "app_deauthorized",
 | 
						|
  "payload": {
 | 
						|
    "user_data_retention": "false",
 | 
						|
    "account_id": "EabCDEFghiLHMA",
 | 
						|
    "user_id": "z9jkdsfsdfjhdkfjQ",
 | 
						|
    "signature": "827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000",
 | 
						|
    "deauthorization_time": "2019-06-17T13:52:28.632Z",
 | 
						|
    "client_id": "ADZ9k9bTWmGUoUbECUKU_a"
 | 
						|
  }
 | 
						|
}
 | 
						|
""",
 | 
						|
            content_type="application/json",
 | 
						|
        )
 | 
						|
        self.assert_json_success(response)
 |