mirror of
https://github.com/gogcom/galaxy-integrations-python-api.git
synced 2025-12-31 19:08:16 -05:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a114c9721c | ||
|
|
6c0389834b | ||
|
|
bc7d1c2914 | ||
|
|
d69e1aaa08 | ||
|
|
c2a0534162 | ||
|
|
1614fd6eb2 | ||
|
|
48e54a8460 | ||
|
|
70a1d5cd1f | ||
|
|
853ecf1d3b | ||
|
|
f025d9f93c | ||
|
|
9f3df6aee3 | ||
|
|
c6d5c55dfd | ||
|
|
d78c08ae4b | ||
|
|
4cec6c09b2 | ||
|
|
3e34edf5e7 | ||
|
|
0d52b3dda6 | ||
|
|
00fe3dd553 | ||
|
|
20143e3b4f | ||
|
|
0b9b2dc8d3 |
@@ -20,3 +20,7 @@ deploy_package:
|
||||
- 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}"
|
||||
when: manual
|
||||
only:
|
||||
- master
|
||||
except:
|
||||
- tags
|
||||
33
README.md
33
README.md
@@ -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
|
||||
```
|
||||
@@ -12,6 +12,7 @@ class Platform(Enum):
|
||||
Battlenet = "battlenet"
|
||||
|
||||
class Feature(Enum):
|
||||
Unknown = "Unknown"
|
||||
ImportInstalledGames = "ImportInstalledGames"
|
||||
ImportOwnedGames = "ImportOwnedGames"
|
||||
LaunchGame = "LaunchGame"
|
||||
@@ -23,11 +24,19 @@ class Feature(Enum):
|
||||
ImportUsers = "ImportUsers"
|
||||
VerifyGame = "VerifyGame"
|
||||
|
||||
class LicenseType(Enum):
|
||||
Unknown = "Unknown"
|
||||
SinglePurchase = "SinglePurchase"
|
||||
FreeToPlay = "FreeToPlay"
|
||||
OtherUserLicense = "OtherUserLicense"
|
||||
|
||||
class LocalGameState(Enum):
|
||||
Unknown = "Unknown"
|
||||
Installed = "Installed"
|
||||
Running = "Running"
|
||||
|
||||
class PresenceState(Enum):
|
||||
Unknown = "Unknown"
|
||||
Online = "online"
|
||||
Offline = "offline"
|
||||
Away = "away"
|
||||
|
||||
77
galaxy/api/errors.py
Normal file
77
galaxy/api/errors.py
Normal 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)
|
||||
@@ -26,9 +26,19 @@ class InvalidParams(JsonRpcError):
|
||||
def __init__(self):
|
||||
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):
|
||||
def __init__(self, data):
|
||||
super().__init__(-32003, "Custom error", data)
|
||||
def __init__(self, code, message, 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])
|
||||
Method = namedtuple("Method", ["callback", "internal"])
|
||||
@@ -54,10 +64,12 @@ class Server():
|
||||
|
||||
async def run(self):
|
||||
while self._active:
|
||||
data = await self._reader.readline()
|
||||
if not data:
|
||||
# on windows rederecting a pipe to stdin result on continues
|
||||
# not-blocking return of empty line on EOF
|
||||
try:
|
||||
data = await self._reader.readline()
|
||||
if not data:
|
||||
self._eof()
|
||||
continue
|
||||
except:
|
||||
self._eof()
|
||||
continue
|
||||
data = data.strip()
|
||||
@@ -139,7 +151,7 @@ class Server():
|
||||
@staticmethod
|
||||
def _parse_request(data):
|
||||
try:
|
||||
jsonrpc_request = json.loads(data)
|
||||
jsonrpc_request = json.loads(data, encoding="utf-8")
|
||||
if jsonrpc_request.get("jsonrpc") != "2.0":
|
||||
raise InvalidRequest()
|
||||
del jsonrpc_request["jsonrpc"]
|
||||
@@ -153,7 +165,7 @@ class Server():
|
||||
try:
|
||||
line = self._encoder.encode(data)
|
||||
logging.debug("Sending data: %s", line)
|
||||
self._writer.write(line + "\n")
|
||||
self._writer.write((line + "\n").encode("utf-8"))
|
||||
asyncio.create_task(self._writer.drain())
|
||||
except TypeError as error:
|
||||
logging.error(str(error))
|
||||
@@ -172,10 +184,13 @@ class Server():
|
||||
"id": request_id,
|
||||
"error": {
|
||||
"code": error.code,
|
||||
"message": error.message,
|
||||
"data": error.data
|
||||
"message": error.message
|
||||
}
|
||||
}
|
||||
|
||||
if error.data is not None:
|
||||
response["error"]["data"] = error.data
|
||||
|
||||
self._send(response)
|
||||
|
||||
class NotificationClient():
|
||||
@@ -196,7 +211,7 @@ class NotificationClient():
|
||||
try:
|
||||
line = self._encoder.encode(data)
|
||||
logging.debug("Sending data: %s", line)
|
||||
self._writer.write(line + "\n")
|
||||
self._writer.write((line + "\n").encode("utf-8"))
|
||||
asyncio.create_task(self._writer.drain())
|
||||
except TypeError as error:
|
||||
logging.error("Failed to parse outgoing message: %s", str(error))
|
||||
|
||||
@@ -6,7 +6,6 @@ from enum import Enum
|
||||
from collections import OrderedDict
|
||||
|
||||
from galaxy.api.jsonrpc import Server, NotificationClient
|
||||
from galaxy.api.stream import stdio
|
||||
from galaxy.api.consts import Feature
|
||||
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
@@ -21,13 +20,14 @@ class JSONEncoder(json.JSONEncoder):
|
||||
return super().default(o)
|
||||
|
||||
class Plugin():
|
||||
def __init__(self, platform):
|
||||
def __init__(self, platform, reader, writer, handshake_token):
|
||||
self._platform = platform
|
||||
|
||||
self._feature_methods = OrderedDict()
|
||||
self._active = True
|
||||
|
||||
self._reader, self._writer = stdio()
|
||||
self._reader, self._writer = reader, writer
|
||||
self._handshake_token = handshake_token
|
||||
|
||||
encoder = JSONEncoder()
|
||||
self._server = Server(self._reader, self._writer, encoder)
|
||||
@@ -44,7 +44,6 @@ class Plugin():
|
||||
|
||||
# implemented by developer
|
||||
self._register_method("init_authentication", self.authenticate)
|
||||
self._register_method("pass_login_credentials", self.pass_login_credentials)
|
||||
self._register_method(
|
||||
"import_owned_games",
|
||||
self.get_owned_games,
|
||||
@@ -182,7 +181,8 @@ class Plugin():
|
||||
def _get_capabilities(self):
|
||||
return {
|
||||
"platform_name": self._platform,
|
||||
"features": self.features
|
||||
"features": self.features,
|
||||
"token": self._handshake_token
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -208,8 +208,12 @@ class Plugin():
|
||||
params = {"owned_game" : game}
|
||||
self._notification_client.notify("owned_game_updated", params)
|
||||
|
||||
def unlock_achievement(self, achievement):
|
||||
self._notification_client.notify("achievement_unlocked", achievement)
|
||||
def unlock_achievement(self, game_id, achievement):
|
||||
params = {
|
||||
"game_id": game_id,
|
||||
"achievement": achievement
|
||||
}
|
||||
self._notification_client.notify("achievement_unlocked", params)
|
||||
|
||||
def update_local_game_status(self, local_game):
|
||||
params = {"local_game" : local_game}
|
||||
@@ -239,6 +243,9 @@ class Plugin():
|
||||
params = {"game_time" : game_time}
|
||||
self._notification_client.notify("game_time_updated", params)
|
||||
|
||||
def lost_authentication(self):
|
||||
self._notification_client.notify("authentication_lost", None)
|
||||
|
||||
# handlers
|
||||
def tick(self):
|
||||
"""This method is called periodicaly.
|
||||
@@ -255,16 +262,11 @@ class Plugin():
|
||||
# methods
|
||||
async def authenticate(self, stored_credentials=None):
|
||||
"""Overide this method to handle plugin authentication.
|
||||
The method should return one of:
|
||||
- galaxy.api.types.AuthenticationSuccess - on successful authencication
|
||||
- galaxy.api.types.NextStep - when more authentication steps are required
|
||||
Or raise galaxy.api.types.LoginError on authentication failure.
|
||||
The method should return galaxy.api.types.Authentication
|
||||
or raise galaxy.api.types.LoginError on authentication failure.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def pass_login_credentials(self, step, credentials):
|
||||
raise NotImplementedError()
|
||||
|
||||
async def get_owned_games(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -306,3 +308,23 @@ class Plugin():
|
||||
|
||||
async def get_game_times(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def create_and_run_plugin(plugin_class, argv):
|
||||
if not issubclass(plugin_class, Plugin):
|
||||
raise TypeError("plugin_class must be subclass of Plugin")
|
||||
if len(argv) < 3:
|
||||
raise ValueError("Not enough parameters, required: token, port")
|
||||
token = argv[1]
|
||||
try:
|
||||
port = int(argv[2])
|
||||
except ValueError as e:
|
||||
raise ValueError("Failed to parse port value, {}".format(e))
|
||||
if not (1 <= port <= 65535):
|
||||
raise ValueError("Port value out of range (1, 65535)")
|
||||
|
||||
async def coroutine():
|
||||
reader, writer = await asyncio.open_connection("127.0.0.1", port)
|
||||
plugin = plugin_class(reader, writer, token)
|
||||
await plugin.run()
|
||||
asyncio.run(coroutine())
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
class StdinReader():
|
||||
def __init__(self):
|
||||
self._stdin = sys.stdin.buffer
|
||||
|
||||
async def readline(self):
|
||||
# a single call to sys.stdin.readline() is thread-safe
|
||||
loop = asyncio.get_running_loop()
|
||||
return await loop.run_in_executor(None, self._stdin.readline)
|
||||
|
||||
class StdoutWriter():
|
||||
def __init__(self):
|
||||
self._buffer = []
|
||||
self._stdout = sys.stdout.buffer
|
||||
|
||||
def write(self, data):
|
||||
self._buffer.append(data)
|
||||
|
||||
async def drain(self):
|
||||
data, self._buffer = self._buffer, []
|
||||
# a single call to sys.stdout.writelines() is thread-safe
|
||||
def write(data):
|
||||
sys.stdout.writelines(data)
|
||||
sys.stdout.flush()
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
return await loop.run_in_executor(None, write, data)
|
||||
|
||||
def stdio():
|
||||
# no support for asyncio stdio yet on Windows, see https://bugs.python.org/issue26832
|
||||
# use an executor to read from stdio and write to stdout
|
||||
# note: if nothing ever drains the writer explicitly, no flushing ever takes place!
|
||||
return StdinReader(), StdoutWriter()
|
||||
@@ -1,31 +1,17 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from galaxy.api.jsonrpc import ApplicationError
|
||||
from galaxy.api.consts import LocalGameState, PresenceState
|
||||
from galaxy.api.consts import LicenseType, LocalGameState, PresenceState
|
||||
|
||||
@dataclass
|
||||
class AuthenticationSuccess():
|
||||
class Authentication():
|
||||
user_id: 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
|
||||
class LicenseInfo():
|
||||
license_type: str
|
||||
owner: str = None
|
||||
license_type: LicenseType
|
||||
owner: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class Dlc():
|
||||
@@ -40,42 +26,21 @@ class Game():
|
||||
dlcs: List[Dlc]
|
||||
license_info: LicenseInfo
|
||||
|
||||
class GetGamesError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
|
||||
@dataclass
|
||||
class Achievement():
|
||||
achievement_id: str
|
||||
unlock_time: int
|
||||
|
||||
class GetAchievementsError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
|
||||
@dataclass
|
||||
class LocalGame():
|
||||
game_id: str
|
||||
local_game_state: LocalGameState
|
||||
|
||||
class GetLocalGamesError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
|
||||
@dataclass
|
||||
class Presence():
|
||||
presence_state: PresenceState
|
||||
game_id: str = None
|
||||
presence_status: str = None
|
||||
game_id: Optional[str] = None
|
||||
presence_status: Optional[str] = None
|
||||
|
||||
@dataclass
|
||||
class UserInfo():
|
||||
@@ -85,47 +50,12 @@ class UserInfo():
|
||||
avatar_url: str
|
||||
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
|
||||
class Room():
|
||||
room_id: str
|
||||
unread_message_count: int
|
||||
last_message_id: str
|
||||
|
||||
class GetRoomsError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
|
||||
@dataclass
|
||||
class Message():
|
||||
message_id: str
|
||||
@@ -133,22 +63,8 @@ class Message():
|
||||
sent_time: int
|
||||
message_text: str
|
||||
|
||||
class GetRoomHistoryError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
|
||||
@dataclass
|
||||
class GameTime():
|
||||
game_id: str
|
||||
time_played: int
|
||||
last_played_time: int
|
||||
|
||||
class GetGameTimeError(ApplicationError):
|
||||
def __init__(self, reason):
|
||||
data = {
|
||||
"reason": reason
|
||||
}
|
||||
super().__init__(data)
|
||||
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="galaxy.plugin.api",
|
||||
version="0.1",
|
||||
version="0.8",
|
||||
description="Galaxy python plugin API",
|
||||
author='Galaxy team',
|
||||
author_email='galaxy@gog.com',
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
from contextlib import ExitStack
|
||||
import logging
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from galaxy.api.plugin import Plugin
|
||||
from galaxy.api.stream import StdinReader, StdoutWriter
|
||||
from galaxy.api.consts import Platform
|
||||
from tests.async_mock import AsyncMock
|
||||
|
||||
@pytest.fixture()
|
||||
def plugin():
|
||||
def reader():
|
||||
stream = MagicMock(name="stream_reader")
|
||||
stream.readline = AsyncMock()
|
||||
yield stream
|
||||
|
||||
@pytest.fixture()
|
||||
def writer():
|
||||
stream = MagicMock(name="stream_writer")
|
||||
stream.write = MagicMock()
|
||||
stream.drain = AsyncMock()
|
||||
yield stream
|
||||
|
||||
@pytest.fixture()
|
||||
def readline(reader):
|
||||
yield reader.readline
|
||||
|
||||
@pytest.fixture()
|
||||
def write(writer):
|
||||
yield writer.write
|
||||
|
||||
@pytest.fixture()
|
||||
def plugin(reader, writer):
|
||||
"""Return plugin instance with all feature methods mocked"""
|
||||
async_methods = (
|
||||
"authenticate",
|
||||
"pass_login_credentials",
|
||||
"get_owned_games",
|
||||
"get_unlocked_achievements",
|
||||
"get_local_games",
|
||||
@@ -41,17 +60,7 @@ def plugin():
|
||||
stack.enter_context(patch.object(Plugin, method, new_callable=AsyncMock))
|
||||
for method in methods:
|
||||
stack.enter_context(patch.object(Plugin, method))
|
||||
yield Plugin(Platform.Generic)
|
||||
|
||||
@pytest.fixture()
|
||||
def readline():
|
||||
with patch.object(StdinReader, "readline", new_callable=AsyncMock) as mock:
|
||||
yield mock
|
||||
|
||||
@pytest.fixture()
|
||||
def write():
|
||||
with patch.object(StdoutWriter, "write") as mock:
|
||||
yield mock
|
||||
yield Plugin(Platform.Generic, reader, writer, "token")
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def my_caplog(caplog):
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import asyncio
|
||||
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):
|
||||
request = {
|
||||
@@ -49,7 +50,7 @@ def test_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_unlocked_achievements.assert_called()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -58,11 +59,8 @@ def test_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +68,7 @@ def test_unlock_achievement(plugin, write):
|
||||
achievement = Achievement("lvl20", 1548422395)
|
||||
|
||||
async def couritine():
|
||||
plugin.unlock_achievement(achievement)
|
||||
plugin.unlock_achievement("14", achievement)
|
||||
|
||||
asyncio.run(couritine())
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -79,7 +77,10 @@ def test_unlock_achievement(plugin, write):
|
||||
"jsonrpc": "2.0",
|
||||
"method": "achievement_unlocked",
|
||||
"params": {
|
||||
"achievement_id": "lvl20",
|
||||
"unlock_time": 1548422395
|
||||
"game_id": "14",
|
||||
"achievement": {
|
||||
"achievement_id": "lvl20",
|
||||
"unlock_time": 1548422395
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import asyncio
|
||||
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):
|
||||
request = {
|
||||
@@ -11,7 +18,7 @@ def test_success(plugin, readline, write):
|
||||
}
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.authenticate.return_value = AuthenticationSuccess("132", "Zenek")
|
||||
plugin.authenticate.return_value = Authentication("132", "Zenek")
|
||||
asyncio.run(plugin.run())
|
||||
plugin.authenticate.assert_called_with()
|
||||
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 = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
@@ -33,7 +56,7 @@ def test_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.authenticate.side_effect = LoginError("step", "reason")
|
||||
plugin.authenticate.side_effect = error()
|
||||
asyncio.run(plugin.run())
|
||||
plugin.authenticate.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -42,12 +65,8 @@ def test_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"current_step": "step",
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +82,7 @@ def test_stored_credentials(plugin, readline, write):
|
||||
}
|
||||
}
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.authenticate.return_value = AuthenticationSuccess("132", "Zenek")
|
||||
plugin.authenticate.return_value = Authentication("132", "Zenek")
|
||||
asyncio.run(plugin.run())
|
||||
plugin.authenticate.assert_called_with(stored_credentials={"token": "ABC"})
|
||||
write.assert_called()
|
||||
@@ -84,3 +103,17 @@ def test_store_credentials(plugin, write):
|
||||
"method": "store_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
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from galaxy.api.types import (
|
||||
SendMessageError, MarkAsReadError, Room, GetRoomsError, Message, GetRoomHistoryError
|
||||
import pytest
|
||||
|
||||
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):
|
||||
@@ -28,7 +32,15 @@ def test_send_message_success(plugin, readline, write):
|
||||
"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 = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "6",
|
||||
@@ -40,7 +52,7 @@ def test_send_message_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.send_message.side_effect = SendMessageError("reason")
|
||||
plugin.send_message.side_effect = error()
|
||||
asyncio.run(plugin.run())
|
||||
plugin.send_message.assert_called_with(room_id="15", message="Bye")
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -49,11 +61,8 @@ def test_send_message_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "6",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +89,20 @@ def test_mark_as_read_success(plugin, readline, write):
|
||||
"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 = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "4",
|
||||
@@ -92,7 +114,7 @@ def test_mark_as_read_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.mark_as_read.assert_called_with(room_id="18", last_message_id="7")
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -101,11 +123,8 @@ def test_mark_as_read_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "4",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +170,7 @@ def test_get_rooms_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.get_rooms.side_effect = GetRoomsError("reason")
|
||||
plugin.get_rooms.side_effect = UnknownError()
|
||||
asyncio.run(plugin.run())
|
||||
plugin.get_rooms.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -160,11 +179,8 @@ def test_get_rooms_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "9",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "7",
|
||||
@@ -221,7 +245,7 @@ def test_get_room_history_from_message_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_room_history_from_message.assert_called_with(room_id="33", message_id="88")
|
||||
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",
|
||||
"id": "7",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +308,7 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_room_history_from_timestamp.assert_called_with(
|
||||
room_id="10",
|
||||
@@ -299,11 +320,8 @@ def test_get_room_history_from_timestamp_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@ from galaxy.api.plugin import Plugin
|
||||
from galaxy.api.consts import Platform, Feature
|
||||
|
||||
def test_base_class():
|
||||
plugin = Plugin(Platform.Generic)
|
||||
plugin = Plugin(Platform.Generic, None, None, None)
|
||||
assert plugin.features == []
|
||||
|
||||
def test_no_overloads():
|
||||
class PluginImpl(Plugin): #pylint: disable=abstract-method
|
||||
pass
|
||||
|
||||
plugin = PluginImpl(Platform.Generic)
|
||||
plugin = PluginImpl(Platform.Generic, None, None, None)
|
||||
assert plugin.features == []
|
||||
|
||||
def test_one_method_feature():
|
||||
@@ -17,7 +17,7 @@ def test_one_method_feature():
|
||||
async def get_owned_games(self):
|
||||
pass
|
||||
|
||||
plugin = PluginImpl(Platform.Generic)
|
||||
plugin = PluginImpl(Platform.Generic, None, None, None)
|
||||
assert plugin.features == [Feature.ImportOwnedGames]
|
||||
|
||||
def test_multiple_methods_feature_all():
|
||||
@@ -33,7 +33,7 @@ def test_multiple_methods_feature_all():
|
||||
async def get_room_history_from_timestamp(self, room_id, timestamp):
|
||||
pass
|
||||
|
||||
plugin = PluginImpl(Platform.Generic)
|
||||
plugin = PluginImpl(Platform.Generic, None, None, None)
|
||||
assert plugin.features == [Feature.Chat]
|
||||
|
||||
def test_multiple_methods_feature_not_all():
|
||||
@@ -41,5 +41,5 @@ def test_multiple_methods_feature_not_all():
|
||||
async def send_message(self, room_id, message):
|
||||
pass
|
||||
|
||||
plugin = PluginImpl(Platform.Generic)
|
||||
plugin = PluginImpl(Platform.Generic, None, None, None)
|
||||
assert plugin.features == []
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import asyncio
|
||||
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):
|
||||
request = {
|
||||
@@ -46,7 +47,7 @@ def test_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_game_times.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -55,11 +56,8 @@ def test_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import json
|
||||
from galaxy.api.plugin import Plugin
|
||||
from galaxy.api.consts import Platform
|
||||
|
||||
def test_get_capabilites(readline, write):
|
||||
def test_get_capabilites(reader, writer, readline, write):
|
||||
class PluginImpl(Plugin): #pylint: disable=abstract-method
|
||||
async def get_owned_games(self):
|
||||
pass
|
||||
@@ -14,7 +14,8 @@ def test_get_capabilites(readline, write):
|
||||
"id": "3",
|
||||
"method": "get_capabilities"
|
||||
}
|
||||
plugin = PluginImpl(Platform.Generic)
|
||||
token = "token"
|
||||
plugin = PluginImpl(Platform.Generic, reader, writer, token)
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
asyncio.run(plugin.run())
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -25,7 +26,8 @@ def test_get_capabilites(readline, write):
|
||||
"platform_name": "generic",
|
||||
"features": [
|
||||
"ImportOwnedGames"
|
||||
]
|
||||
],
|
||||
"token": token
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import asyncio
|
||||
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.errors import UnknownError, FailedParsingManifest
|
||||
|
||||
def test_success(plugin, readline, write):
|
||||
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 = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
@@ -46,7 +56,7 @@ def test_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_local_games.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -55,11 +65,8 @@ def test_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": code,
|
||||
"message": message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from galaxy.api.types import Game, Dlc, LicenseInfo, GetGamesError
|
||||
from galaxy.api.types import Game, Dlc, LicenseInfo
|
||||
from galaxy.api.consts import LicenseType
|
||||
from galaxy.api.errors import UnknownError
|
||||
|
||||
def test_success(plugin, readline, write):
|
||||
request = {
|
||||
@@ -12,15 +14,15 @@ def test_success(plugin, readline, write):
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.get_owned_games.return_value = [
|
||||
Game("3", "Doom", None, LicenseInfo("SinglePurchase", None)),
|
||||
Game("3", "Doom", None, LicenseInfo(LicenseType.SinglePurchase, None)),
|
||||
Game(
|
||||
"5",
|
||||
"Witcher 3",
|
||||
[
|
||||
Dlc("7", "Hearts of Stone", LicenseInfo("SinglePurchase", None)),
|
||||
Dlc("8", "Temerian Armor Set", LicenseInfo("FreeToPlay", None)),
|
||||
Dlc("7", "Hearts of Stone", LicenseInfo(LicenseType.SinglePurchase, None)),
|
||||
Dlc("8", "Temerian Armor Set", LicenseInfo(LicenseType.FreeToPlay, None)),
|
||||
],
|
||||
LicenseInfo("SinglePurchase", None))
|
||||
LicenseInfo(LicenseType.SinglePurchase, None))
|
||||
]
|
||||
asyncio.run(plugin.run())
|
||||
plugin.get_owned_games.assert_called_with()
|
||||
@@ -73,7 +75,7 @@ def test_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
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())
|
||||
plugin.get_owned_games.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -82,16 +84,13 @@ def test_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
def test_add_game(plugin, write):
|
||||
game = Game("3", "Doom", None, LicenseInfo("SinglePurchase", None))
|
||||
game = Game("3", "Doom", None, LicenseInfo(LicenseType.SinglePurchase, None))
|
||||
|
||||
async def couritine():
|
||||
plugin.add_game(game)
|
||||
@@ -129,7 +128,7 @@ def test_remove_game(plugin, write):
|
||||
}
|
||||
|
||||
def test_update_game(plugin, write):
|
||||
game = Game("3", "Doom", None, LicenseInfo("SinglePurchase", None))
|
||||
game = Game("3", "Doom", None, LicenseInfo(LicenseType.SinglePurchase, None))
|
||||
|
||||
async def couritine():
|
||||
plugin.update_game(game)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import asyncio
|
||||
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
|
||||
|
||||
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), ""]
|
||||
plugin.get_friends.side_effect = GetFriendsError("reason")
|
||||
plugin.get_friends.side_effect = UnknownError()
|
||||
asyncio.run(plugin.run())
|
||||
plugin.get_friends.assert_called_with()
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -82,11 +83,8 @@ def test_get_friends_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "3",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +200,7 @@ def test_get_users_failure(plugin, readline, write):
|
||||
}
|
||||
|
||||
readline.side_effect = [json.dumps(request), ""]
|
||||
plugin.get_users.side_effect = GetUsersError("reason")
|
||||
plugin.get_users.side_effect = UnknownError()
|
||||
asyncio.run(plugin.run())
|
||||
plugin.get_users.assert_called_with(user_id_list=["10", "11", "12"])
|
||||
response = json.loads(write.call_args[0][0])
|
||||
@@ -211,10 +209,7 @@ def test_get_users_failure(plugin, readline, write):
|
||||
"jsonrpc": "2.0",
|
||||
"id": "12",
|
||||
"error": {
|
||||
"code": -32003,
|
||||
"message": "Custom error",
|
||||
"data": {
|
||||
"reason": "reason"
|
||||
}
|
||||
"code": 0,
|
||||
"message": "Unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user