Compare commits

..

10 Commits
0.1 ... 0.3

Author SHA1 Message Date
Romuald Juchnowicz-Bierbasz
f025d9f93c SDK-2525: Increment version 2019-02-15 10:16:38 +01:00
Romuald Juchnowicz-Bierbasz
9f3df6aee3 SDK-2525: Add AuthenticationRequired error, change codes 2019-02-15 10:16:26 +01:00
Romuald Juchnowicz-Bierbasz
c6d5c55dfd SDK-2525: Refactor errors 2019-02-13 12:53:25 +01:00
Rafal Makagon
d78c08ae4b add authentication lost notification 2019-02-13 10:40:08 +01:00
Romuald Bierbasz
4cec6c09b2 SDK-2524: Fix achievement notification 2019-02-13 10:22:36 +01:00
Romuald Juchnowicz-Bierbasz
3e34edf5e7 Increment version 2019-02-13 08:23:07 +01:00
Romuald Juchnowicz-Bierbasz
0d52b3dda6 SDK-2526: Refactor authentication 2019-02-12 17:55:28 +01:00
Romuald Juchnowicz-Bierbasz
00fe3dd553 SDK-2520: Skipt deployment for tags 2019-02-11 15:12:57 +01:00
Romuald Juchnowicz-Bierbasz
20143e3b4f SDK-2520: Fix typo 2019-02-11 15:11:18 +01:00
Romuald Juchnowicz-Bierbasz
0b9b2dc8d3 SDK-2520: Add docs 2019-02-11 15:09:23 +01:00
15 changed files with 282 additions and 193 deletions

View File

@@ -20,3 +20,5 @@ deploy_package:
- curl -X POST --silent --show-error --fail - curl -X POST --silent --show-error --fail
"https://gitlab.gog.com/api/v4/projects/${CI_PROJECT_ID}/repository/tags?tag_name=${VERSION}&ref=${CI_COMMIT_REF_NAME}&private_token=${PACKAGE_DEPLOYER_API_TOKEN}" "https://gitlab.gog.com/api/v4/projects/${CI_PROJECT_ID}/repository/tags?tag_name=${VERSION}&ref=${CI_COMMIT_REF_NAME}&private_token=${PACKAGE_DEPLOYER_API_TOKEN}"
when: manual when: manual
except:
- tags

View File

@@ -1,2 +1,33 @@
# galaxy-plugin-api # Galaxy python plugin API
## Usage
Implement plugin:
```python
import asyncio
from galaxy.api.plugin import Plugin
class PluginExample(Plugin):
# implement methods
async def authenticate(self, stored_credentials=None):
pass
# run plugin event loop
if __name__ == "__main__":
asyncio.run(MockPlugin().run())
```
Use [pyinstaller](https://www.pyinstaller.org/) to create plugin executbale.
## Development
Install required packages:
```bash
pip install -r requirements.txt
```
Run tests:
```bash
pytest
```

77
galaxy/api/errors.py Normal file
View File

@@ -0,0 +1,77 @@
from galaxy.api.jsonrpc import ApplicationError
class UnknownError(ApplicationError):
def __init__(self, data=None):
super().__init__(0, "Unknown error", data)
class AuthenticationRequired(ApplicationError):
def __init__(self, data=None):
super().__init__(1, "Authentication required", data)
class BackendNotAvailable(ApplicationError):
def __init__(self, data=None):
super().__init__(2, "Backend not available", data)
class BackendTimeout(ApplicationError):
def __init__(self, data=None):
super().__init__(3, "Backend timed out", data)
class BackendError(ApplicationError):
def __init__(self, data=None):
super().__init__(4, "Backend error", data)
class InvalidCredentials(ApplicationError):
def __init__(self, data=None):
super().__init__(100, "Invalid credentials", data)
class NetworkError(ApplicationError):
def __init__(self, data=None):
super().__init__(101, "Network error", data)
class LoggedInElsewhere(ApplicationError):
def __init__(self, data=None):
super().__init__(102, "Logged in elsewhere", data)
class ProtocolError(ApplicationError):
def __init__(self, data=None):
super().__init__(103, "Protocol error", data)
class TemporaryBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(104, "Temporary blocked", data)
class Banned(ApplicationError):
def __init__(self, data=None):
super().__init__(105, "Banned", data)
class AccessDenied(ApplicationError):
def __init__(self, data=None):
super().__init__(106, "Access denied", data)
class ParentalControlBlock(ApplicationError):
def __init__(self, data=None):
super().__init__(107, "Parental control block", data)
class DeviceBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(108, "Device blocked", data)
class RegionBlocked(ApplicationError):
def __init__(self, data=None):
super().__init__(109, "Region blocked", data)
class FailedParsingManifest(ApplicationError):
def __init__(self, data=None):
super().__init__(200, "Failed parsing manifest", data)
class TooManyMessagesSent(ApplicationError):
def __init__(self, data=None):
super().__init__(300, "Too many messages sent", data)
class IncoherentLastMessage(ApplicationError):
def __init__(self, data=None):
super().__init__(400, "Different last message id on backend", data)
class MessageNotFound(ApplicationError):
def __init__(self, data=None):
super().__init__(500, "Message not found", data)

View File

@@ -26,9 +26,19 @@ class InvalidParams(JsonRpcError):
def __init__(self): def __init__(self):
super().__init__(-32601, "Invalid params") super().__init__(-32601, "Invalid params")
class Timeout(JsonRpcError):
def __init__(self):
super().__init__(-32000, "Method timed out")
class Aborted(JsonRpcError):
def __init__(self):
super().__init__(-32001, "Method aborted")
class ApplicationError(JsonRpcError): class ApplicationError(JsonRpcError):
def __init__(self, data): def __init__(self, code, message, data):
super().__init__(-32003, "Custom error", data) if code >= -32768 and code <= -32000:
raise ValueError("The error code in reserved range")
super().__init__(code, message, data)
Request = namedtuple("Request", ["method", "params", "id"], defaults=[{}, None]) Request = namedtuple("Request", ["method", "params", "id"], defaults=[{}, None])
Method = namedtuple("Method", ["callback", "internal"]) Method = namedtuple("Method", ["callback", "internal"])
@@ -172,10 +182,13 @@ class Server():
"id": request_id, "id": request_id,
"error": { "error": {
"code": error.code, "code": error.code,
"message": error.message, "message": error.message
"data": error.data
} }
} }
if error.data is not None:
response["error"]["data"] = error.data
self._send(response) self._send(response)
class NotificationClient(): class NotificationClient():

View File

@@ -44,7 +44,6 @@ class Plugin():
# implemented by developer # implemented by developer
self._register_method("init_authentication", self.authenticate) self._register_method("init_authentication", self.authenticate)
self._register_method("pass_login_credentials", self.pass_login_credentials)
self._register_method( self._register_method(
"import_owned_games", "import_owned_games",
self.get_owned_games, self.get_owned_games,
@@ -208,8 +207,12 @@ class Plugin():
params = {"owned_game" : game} params = {"owned_game" : game}
self._notification_client.notify("owned_game_updated", params) self._notification_client.notify("owned_game_updated", params)
def unlock_achievement(self, achievement): def unlock_achievement(self, game_id, achievement):
self._notification_client.notify("achievement_unlocked", achievement) params = {
"game_id": game_id,
"achievement": achievement
}
self._notification_client.notify("achievement_unlocked", params)
def update_local_game_status(self, local_game): def update_local_game_status(self, local_game):
params = {"local_game" : local_game} params = {"local_game" : local_game}
@@ -239,6 +242,9 @@ class Plugin():
params = {"game_time" : game_time} params = {"game_time" : game_time}
self._notification_client.notify("game_time_updated", params) self._notification_client.notify("game_time_updated", params)
def lost_authentication(self):
self._notification_client.notify("authentication_lost", None)
# handlers # handlers
def tick(self): def tick(self):
"""This method is called periodicaly. """This method is called periodicaly.
@@ -255,16 +261,11 @@ class Plugin():
# methods # methods
async def authenticate(self, stored_credentials=None): async def authenticate(self, stored_credentials=None):
"""Overide this method to handle plugin authentication. """Overide this method to handle plugin authentication.
The method should return one of: The method should return galaxy.api.types.Authentication
- galaxy.api.types.AuthenticationSuccess - on successful authencication or raise galaxy.api.types.LoginError on authentication failure.
- galaxy.api.types.NextStep - when more authentication steps are required
Or raise galaxy.api.types.LoginError on authentication failure.
""" """
raise NotImplementedError() raise NotImplementedError()
async def pass_login_credentials(self, step, credentials):
raise NotImplementedError()
async def get_owned_games(self): async def get_owned_games(self):
raise NotImplementedError() raise NotImplementedError()

View File

@@ -1,27 +1,13 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List from typing import List
from galaxy.api.jsonrpc import ApplicationError
from galaxy.api.consts import LocalGameState, PresenceState from galaxy.api.consts import LocalGameState, PresenceState
@dataclass @dataclass
class AuthenticationSuccess(): class Authentication():
user_id: str user_id: str
user_name: str user_name: str
@dataclass
class NextStep():
next_step: str
auth_params: dict
class LoginError(ApplicationError):
def __init__(self, current_step, reason):
data = {
"current_step": current_step,
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class LicenseInfo(): class LicenseInfo():
license_type: str license_type: str
@@ -40,37 +26,16 @@ class Game():
dlcs: List[Dlc] dlcs: List[Dlc]
license_info: LicenseInfo license_info: LicenseInfo
class GetGamesError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class Achievement(): class Achievement():
achievement_id: str achievement_id: str
unlock_time: int unlock_time: int
class GetAchievementsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class LocalGame(): class LocalGame():
game_id: str game_id: str
local_game_state: LocalGameState local_game_state: LocalGameState
class GetLocalGamesError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class Presence(): class Presence():
presence_state: PresenceState presence_state: PresenceState
@@ -85,47 +50,12 @@ class UserInfo():
avatar_url: str avatar_url: str
presence: Presence presence: Presence
class GetFriendsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class GetUsersError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class SendMessageError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
class MarkAsReadError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class Room(): class Room():
room_id: str room_id: str
unread_message_count: int unread_message_count: int
last_message_id: str last_message_id: str
class GetRoomsError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class Message(): class Message():
message_id: str message_id: str
@@ -133,22 +63,8 @@ class Message():
sent_time: int sent_time: int
message_text: str message_text: str
class GetRoomHistoryError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)
@dataclass @dataclass
class GameTime(): class GameTime():
game_id: str game_id: str
time_played: int time_played: int
last_played_time: int last_played_time: int
class GetGameTimeError(ApplicationError):
def __init__(self, reason):
data = {
"reason": reason
}
super().__init__(data)

View File

@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup( setup(
name="galaxy.plugin.api", name="galaxy.plugin.api",
version="0.1", version="0.3",
description="Galaxy python plugin API", description="Galaxy python plugin API",
author='Galaxy team', author='Galaxy team',
author_email='galaxy@gog.com', author_email='galaxy@gog.com',

View File

@@ -14,7 +14,6 @@ def plugin():
"""Return plugin instance with all feature methods mocked""" """Return plugin instance with all feature methods mocked"""
async_methods = ( async_methods = (
"authenticate", "authenticate",
"pass_login_credentials",
"get_owned_games", "get_owned_games",
"get_unlocked_achievements", "get_unlocked_achievements",
"get_local_games", "get_local_games",

View File

@@ -1,7 +1,8 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import Achievement, GetAchievementsError from galaxy.api.types import Achievement
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write): def test_success(plugin, readline, write):
request = { request = {
@@ -49,7 +50,7 @@ def test_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_unlocked_achievements.side_effect = GetAchievementsError("reason") plugin.get_unlocked_achievements.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_unlocked_achievements.assert_called() plugin.get_unlocked_achievements.assert_called()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -58,11 +59,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error"
"data": {
"reason": "reason"
}
} }
} }
@@ -70,7 +68,7 @@ def test_unlock_achievement(plugin, write):
achievement = Achievement("lvl20", 1548422395) achievement = Achievement("lvl20", 1548422395)
async def couritine(): async def couritine():
plugin.unlock_achievement(achievement) plugin.unlock_achievement("14", achievement)
asyncio.run(couritine()) asyncio.run(couritine())
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -79,7 +77,10 @@ def test_unlock_achievement(plugin, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "achievement_unlocked", "method": "achievement_unlocked",
"params": { "params": {
"achievement_id": "lvl20", "game_id": "14",
"unlock_time": 1548422395 "achievement": {
"achievement_id": "lvl20",
"unlock_time": 1548422395
}
} }
} }

View File

@@ -1,7 +1,14 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import AuthenticationSuccess, LoginError import pytest
from galaxy.api.types import Authentication
from galaxy.api.errors import (
UnknownError, InvalidCredentials, NetworkError, LoggedInElsewhere, ProtocolError,
BackendNotAvailable, BackendTimeout, BackendError, TemporaryBlocked, Banned, AccessDenied,
ParentalControlBlock, DeviceBlocked, RegionBlocked
)
def test_success(plugin, readline, write): def test_success(plugin, readline, write):
request = { request = {
@@ -11,7 +18,7 @@ def test_success(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.authenticate.return_value = AuthenticationSuccess("132", "Zenek") plugin.authenticate.return_value = Authentication("132", "Zenek")
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.authenticate.assert_called_with() plugin.authenticate.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -25,7 +32,23 @@ def test_success(plugin, readline, write):
} }
} }
def test_failure(plugin, readline, write): @pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(BackendNotAvailable, 2, "Backend not available", id="backend_not_available"),
pytest.param(BackendTimeout, 3, "Backend timed out", id="backend_timeout"),
pytest.param(BackendError, 4, "Backend error", id="backend_error"),
pytest.param(InvalidCredentials, 100, "Invalid credentials", id="invalid_credentials"),
pytest.param(NetworkError, 101, "Network error", id="network_error"),
pytest.param(LoggedInElsewhere, 102, "Logged in elsewhere", id="logged_elsewhere"),
pytest.param(ProtocolError, 103, "Protocol error", id="protocol_error"),
pytest.param(TemporaryBlocked, 104, "Temporary blocked", id="temporary_blocked"),
pytest.param(Banned, 105, "Banned", id="banned"),
pytest.param(AccessDenied, 106, "Access denied", id="access_denied"),
pytest.param(ParentalControlBlock, 107, "Parental control block", id="parental_control_clock"),
pytest.param(DeviceBlocked, 108, "Device blocked", id="device_blocked"),
pytest.param(RegionBlocked, 109, "Region blocked", id="region_blocked")
])
def test_failure(plugin, readline, write, error, code, message):
request = { request = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
@@ -33,7 +56,7 @@ def test_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.authenticate.side_effect = LoginError("step", "reason") plugin.authenticate.side_effect = error()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.authenticate.assert_called_with() plugin.authenticate.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -42,12 +65,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": code,
"message": "Custom error", "message": message
"data": {
"current_step": "step",
"reason": "reason"
}
} }
} }
@@ -63,7 +82,7 @@ def test_stored_credentials(plugin, readline, write):
} }
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.authenticate.return_value = AuthenticationSuccess("132", "Zenek") plugin.authenticate.return_value = Authentication("132", "Zenek")
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.authenticate.assert_called_with(stored_credentials={"token": "ABC"}) plugin.authenticate.assert_called_with(stored_credentials={"token": "ABC"})
write.assert_called() write.assert_called()
@@ -84,3 +103,17 @@ def test_store_credentials(plugin, write):
"method": "store_credentials", "method": "store_credentials",
"params": credentials "params": credentials
} }
def test_lost_authentication(plugin, readline, write):
async def couritine():
plugin.lost_authentication()
asyncio.run(couritine())
response = json.loads(write.call_args[0][0])
assert response == {
"jsonrpc": "2.0",
"method": "authentication_lost",
"params": None
}

View File

@@ -1,8 +1,12 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import ( import pytest
SendMessageError, MarkAsReadError, Room, GetRoomsError, Message, GetRoomHistoryError
from galaxy.api.types import Room, Message
from galaxy.api.errors import (
UnknownError, AuthenticationRequired, BackendNotAvailable, BackendTimeout, BackendError,
TooManyMessagesSent, IncoherentLastMessage, MessageNotFound
) )
def test_send_message_success(plugin, readline, write): def test_send_message_success(plugin, readline, write):
@@ -28,7 +32,15 @@ def test_send_message_success(plugin, readline, write):
"result": None "result": None
} }
def test_send_message_failure(plugin, readline, write): @pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(AuthenticationRequired, 1, "Authentication required", id="not_authenticated"),
pytest.param(BackendNotAvailable, 2, "Backend not available", id="backend_not_available"),
pytest.param(BackendTimeout, 3, "Backend timed out", id="backend_timeout"),
pytest.param(BackendError, 4, "Backend error", id="backend_error"),
pytest.param(TooManyMessagesSent, 300, "Too many messages sent", id="too_many_messages")
])
def test_send_message_failure(plugin, readline, write, error, code, message):
request = { request = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "6", "id": "6",
@@ -40,7 +52,7 @@ def test_send_message_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.send_message.side_effect = SendMessageError("reason") plugin.send_message.side_effect = error()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.send_message.assert_called_with(room_id="15", message="Bye") plugin.send_message.assert_called_with(room_id="15", message="Bye")
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -49,11 +61,8 @@ def test_send_message_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "6", "id": "6",
"error": { "error": {
"code": -32003, "code": code,
"message": "Custom error", "message": message
"data": {
"reason": "reason"
}
} }
} }
@@ -80,7 +89,20 @@ def test_mark_as_read_success(plugin, readline, write):
"result": None "result": None
} }
def test_mark_as_read_failure(plugin, readline, write): @pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(AuthenticationRequired, 1, "Authentication required", id="not_authenticated"),
pytest.param(BackendNotAvailable, 2, "Backend not available", id="backend_not_available"),
pytest.param(BackendTimeout, 3, "Backend timed out", id="backend_timeout"),
pytest.param(BackendError, 4, "Backend error", id="backend_error"),
pytest.param(
IncoherentLastMessage,
400,
"Different last message id on backend",
id="incoherent_last_message"
)
])
def test_mark_as_read_failure(plugin, readline, write, error, code, message):
request = { request = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "4", "id": "4",
@@ -92,7 +114,7 @@ def test_mark_as_read_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.mark_as_read.side_effect = MarkAsReadError("reason") plugin.mark_as_read.side_effect = error()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.mark_as_read.assert_called_with(room_id="18", last_message_id="7") plugin.mark_as_read.assert_called_with(room_id="18", last_message_id="7")
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -101,11 +123,8 @@ def test_mark_as_read_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "4", "id": "4",
"error": { "error": {
"code": -32003, "code": code,
"message": "Custom error", "message": message
"data": {
"reason": "reason"
}
} }
} }
@@ -151,7 +170,7 @@ def test_get_rooms_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_rooms.side_effect = GetRoomsError("reason") plugin.get_rooms.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_rooms.assert_called_with() plugin.get_rooms.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -160,11 +179,8 @@ def test_get_rooms_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "9", "id": "9",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error"
"data": {
"reason": "reason"
}
} }
} }
@@ -209,7 +225,15 @@ def test_get_room_history_from_message_success(plugin, readline, write):
} }
} }
def test_get_room_history_from_message_failure(plugin, readline, write): @pytest.mark.parametrize("error,code,message", [
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(AuthenticationRequired, 1, "Authentication required", id="not_authenticated"),
pytest.param(BackendNotAvailable, 2, "Backend not available", id="backend_not_available"),
pytest.param(BackendTimeout, 3, "Backend timed out", id="backend_timeout"),
pytest.param(BackendError, 4, "Backend error", id="backend_error"),
pytest.param(MessageNotFound, 500, "Message not found", id="message_not_found")
])
def test_get_room_history_from_message_failure(plugin, readline, write, error, code, message):
request = { request = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "7", "id": "7",
@@ -221,7 +245,7 @@ def test_get_room_history_from_message_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_room_history_from_message.side_effect = GetRoomHistoryError("reason") plugin.get_room_history_from_message.side_effect = error()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_room_history_from_message.assert_called_with(room_id="33", message_id="88") plugin.get_room_history_from_message.assert_called_with(room_id="33", message_id="88")
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -230,11 +254,8 @@ def test_get_room_history_from_message_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "7", "id": "7",
"error": { "error": {
"code": -32003, "code": code,
"message": "Custom error", "message": message
"data": {
"reason": "reason"
}
} }
} }
@@ -287,7 +308,7 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_room_history_from_timestamp.side_effect = GetRoomHistoryError("reason") plugin.get_room_history_from_timestamp.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_room_history_from_timestamp.assert_called_with( plugin.get_room_history_from_timestamp.assert_called_with(
room_id="10", room_id="10",
@@ -299,11 +320,8 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error"
"data": {
"reason": "reason"
}
} }
} }

View File

@@ -1,7 +1,8 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import GameTime, GetGameTimeError from galaxy.api.types import GameTime
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write): def test_success(plugin, readline, write):
request = { request = {
@@ -46,7 +47,7 @@ def test_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_game_times.side_effect = GetGameTimeError("reason") plugin.get_game_times.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_game_times.assert_called_with() plugin.get_game_times.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -55,11 +56,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error",
"data": {
"reason": "reason"
}
} }
} }

View File

@@ -1,8 +1,11 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import GetLocalGamesError, LocalGame import pytest
from galaxy.api.types import LocalGame
from galaxy.api.consts import LocalGameState from galaxy.api.consts import LocalGameState
from galaxy.api.errors import UnknownError, FailedParsingManifest
def test_success(plugin, readline, write): def test_success(plugin, readline, write):
request = { request = {
@@ -38,7 +41,14 @@ def test_success(plugin, readline, write):
} }
} }
def test_failure(plugin, readline, write): @pytest.mark.parametrize(
"error,code,message",
[
pytest.param(UnknownError, 0, "Unknown error", id="unknown_error"),
pytest.param(FailedParsingManifest, 200, "Failed parsing manifest", id="failed_parsing")
],
)
def test_failure(plugin, readline, write, error, code, message):
request = { request = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
@@ -46,7 +56,7 @@ def test_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_local_games.side_effect = GetLocalGamesError("reason") plugin.get_local_games.side_effect = error()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_local_games.assert_called_with() plugin.get_local_games.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -55,11 +65,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": code,
"message": "Custom error", "message": message
"data": {
"reason": "reason"
}
} }
} }

View File

@@ -1,7 +1,8 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import Game, Dlc, LicenseInfo, GetGamesError from galaxy.api.types import Game, Dlc, LicenseInfo
from galaxy.api.errors import UnknownError
def test_success(plugin, readline, write): def test_success(plugin, readline, write):
request = { request = {
@@ -73,7 +74,7 @@ def test_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_owned_games.side_effect = GetGamesError("reason") plugin.get_owned_games.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_owned_games.assert_called_with() plugin.get_owned_games.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -82,11 +83,8 @@ def test_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error"
"data": {
"reason": "reason"
}
} }
} }

View File

@@ -1,7 +1,8 @@
import asyncio import asyncio
import json import json
from galaxy.api.types import UserInfo, Presence, GetFriendsError, GetUsersError from galaxy.api.types import UserInfo, Presence
from galaxy.api.errors import UnknownError
from galaxy.api.consts import PresenceState from galaxy.api.consts import PresenceState
def test_get_friends_success(plugin, readline, write): def test_get_friends_success(plugin, readline, write):
@@ -73,7 +74,7 @@ def test_get_friends_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_friends.side_effect = GetFriendsError("reason") plugin.get_friends.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_friends.assert_called_with() plugin.get_friends.assert_called_with()
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -82,11 +83,8 @@ def test_get_friends_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "3", "id": "3",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error",
"data": {
"reason": "reason"
}
} }
} }
@@ -202,7 +200,7 @@ def test_get_users_failure(plugin, readline, write):
} }
readline.side_effect = [json.dumps(request), ""] readline.side_effect = [json.dumps(request), ""]
plugin.get_users.side_effect = GetUsersError("reason") plugin.get_users.side_effect = UnknownError()
asyncio.run(plugin.run()) asyncio.run(plugin.run())
plugin.get_users.assert_called_with(user_id_list=["10", "11", "12"]) plugin.get_users.assert_called_with(user_id_list=["10", "11", "12"])
response = json.loads(write.call_args[0][0]) response = json.loads(write.call_args[0][0])
@@ -211,10 +209,7 @@ def test_get_users_failure(plugin, readline, write):
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "12", "id": "12",
"error": { "error": {
"code": -32003, "code": 0,
"message": "Custom error", "message": "Unknown error"
"data": {
"reason": "reason"
}
} }
} }