فهرست منبع

Move methods from authentication to api wrapper

JoostSijm 4 سال پیش
والد
کامیت
5e737b9edd

+ 2 - 2
src/rival_regions_wrapper/__init__.py

@@ -38,5 +38,5 @@ FILE_HANDLER.setFormatter(FILE_FORMATTER)
 LOGGER.addHandler(STREAM_HANDLER)
 LOGGER.addHandler(FILE_HANDLER)
 
-from .authentication_handler import AuthenticationHandler
-from .middleware import LocalAuthentication, RemoteAuthentication
+# from .authentication_handler import AuthenticationHandler
+# from .middleware import LocalAuthentication, RemoteAuthentication

+ 150 - 4
src/rival_regions_wrapper/api_wrapper/conference.py

@@ -1,10 +1,156 @@
 """Conference class"""
 
-from .abstract_wrapper import AbstractWrapper
+import time
+
+from rival_regions_wrapper import authentication_handler, LOGGER
+from rival_regions_wrapper.browser import Browser
+from rival_regions_wrapper.cookie_handler import CookieHandler
+from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Conference(AbstractWrapper):
     """Wrapper class for confernce"""
-    def send_message(self, conference_id, message):
-        """send conference message"""
-        self.api_wrapper.send_conference_message(conference_id, message)
+    def __init__(self, api_wrapper, conference_id):
+        AbstractWrapper.__init__(self, api_wrapper)
+        self.conference_id = conference_id
+
+    @authentication_handler.session_handler
+    def message(self, message):
+        """Send message to conference"""
+        LOGGER.info(
+                '"%s": CONF "%s": start send message',
+                self.api_wrapper.client.username, self.conference_id
+            )
+        if self.api_wrapper.client.session:
+            response = self.api_wrapper.client.session.get(
+                    "https://rivalregions.com/#overview"
+                )
+            self.api_wrapper.client.check_response(response)
+            browser = Browser(showWindow=self.api_wrapper.client.show_window)
+            browser.go_to('https://rivalregions.com/')
+            for cookie_name, value in \
+                    self.api_wrapper.client.session.cookies.get_dict().items():
+                browser.add_cookie(
+                        CookieHandler.create_cookie(cookie_name, None, value)
+                    )
+            browser.go_to(
+                    'https://rivalregions.com/#slide/conference/{}'
+                    .format(self.conference_id)
+                )
+            browser.refresh()
+            time.sleep(2)
+
+            character_count = 0
+            tmp_messages = []
+            for sentence in message.split('\n'):
+                sentence_character_count = 0
+                tmp_sentence = []
+                for word in sentence.split(' '):
+                    sentence_character_count += len(word) + 1
+                    if sentence_character_count >= 899:
+                        message = '{}\n{}'.format('\n'.join(
+                                tmp_messages),
+                                ' '.join(tmp_sentence)
+                            )
+                        LOGGER.info(
+                                '"%s": CONF "%s": next message length: %s',
+                                self.api_wrapper.client.username,
+                                self.conference_id, len(message)
+                            )
+                        browser.type(message, id='message')
+                        browser.click(id='chat_send')
+                        sentence_character_count = 0
+                        tmp_sentence = []
+                        character_count = 0
+                        tmp_messages = []
+                    tmp_sentence.append(word)
+
+                sentence = ' '.join(tmp_sentence)
+                character_count += len(sentence) + 1
+                if character_count >= 900:
+                    message = '\n'.join(tmp_messages)
+                    LOGGER.info(
+                            '"%s": CONF "%s": next message length: %s',
+                            self.api_wrapper.client.username,
+                            self.conference_id, len(message)
+                        )
+                    browser.type(message, id='message')
+                    browser.click(id='chat_send')
+                    character_count = 0
+                    tmp_messages = []
+                tmp_messages.append(sentence)
+
+            if tmp_messages:
+                message = '\n'.join(tmp_messages)
+                LOGGER.info(
+                        '"%s": CONF "%s": next message length: %s',
+                        self.api_wrapper.client.username,
+                        self.conference_id, len(message)
+                    )
+                browser.type(message, id='message')
+                browser.click(id='chat_send')
+
+            LOGGER.info(
+                    '"%s": CONF "%s": finished sending message',
+                    self.api_wrapper.client.username, self.conference_id
+                )
+            browser.close_current_tab()
+        else:
+            raise authentication_handler.NoLogginException()
+
+    @authentication_handler.session_handler
+    def notification(self, message, sound):
+        """Send notification to conference"""
+        LOGGER.info(
+                '"%s": CONF: %s notification',
+                self.api_wrapper.client.username, self.conference_id
+            )
+        data = {
+            'sound': 1 if sound else 0,
+            'text': message,
+            'c': self.api_wrapper.client.var_c,
+        }
+
+        if self.api_wrapper.client.session:
+            response = self.api_wrapper.client.session.post(
+                "https://rivalregions.com/rival/konffcm/{}/".format(
+                    self.conference_id
+                ),
+                data=data
+            )
+            self.api_wrapper.client.check_response(response)
+        else:
+            raise authentication_handler.NoLogginException()
+        LOGGER.info(
+                '"%s": CONF: id %s send notification ',
+                self.api_wrapper.client.username, self.conference_id
+            )
+        return response.text
+
+    @authentication_handler.session_handler
+    def change_title(self, title):
+        """Change title of conference"""
+        LOGGER.info(
+                '"%s": CONF: %s change title: %s',
+                self.api_wrapper.client.username, self.conference_id, title
+            )
+        data = {
+            't': title,
+            'c': self.api_wrapper.client.var_c,
+        }
+
+        if self.api_wrapper.client.session:
+            response = self.api_wrapper.client.session.post(
+                "https://rivalregions.com/rival/changename/{}/".format(
+                    self.conference_id
+                ),
+                data=data
+            )
+            self.api_wrapper.client.check_response(response)
+        else:
+            raise authentication_handler.NoLogginException()
+        LOGGER.info(
+                '"%s": CONF: id %s changed title',
+                self.api_wrapper.client.username, self.conference_id
+            )
+        return response.text

+ 50 - 0
src/rival_regions_wrapper/api_wrapper/language_chat.py

@@ -0,0 +1,50 @@
+"""Language chat class"""
+
+import time
+
+from rival_regions_wrapper import authentication_handler, LOGGER
+from rival_regions_wrapper.browser import Browser
+from rival_regions_wrapper.cookie_handler import CookieHandler
+from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
+
+
+class LanguageChat(AbstractWrapper):
+    """Wrapper class for language chat"""
+    def __init__(self, api_wrapper, language):
+        AbstractWrapper.__init__(self, api_wrapper)
+        self.language = language
+
+    @authentication_handler.session_handler
+    def message(self, message):
+        """send message to language chat"""
+        LOGGER.info(
+                '"%s": CHAT: language %s',
+                self.api_wrapper.client.username, self.language
+            )
+        if self.api_wrapper.client.session:
+            response = self.api_wrapper.client.session.get(
+                    "https://rivalregions.com/#overview"
+                )
+            self.api_wrapper.client.check_response(response)
+            browser = Browser(showWindow=self.api_wrapper.client.show_window)
+            browser.go_to('https://rivalregions.com/')
+            for cookie_name, value in \
+                    self.api_wrapper.client.session.cookies.get_dict().items():
+                browser.add_cookie(
+                        CookieHandler.create_cookie(cookie_name, None, value)
+                    )
+            browser.go_to(
+                    'https://rivalregions.com/#slide/chat/lang_{}'
+                    .format(self.language)
+                )
+            browser.refresh()
+            time.sleep(2)
+            browser.type(message, id='message')
+            browser.click(id='chat_send')
+            LOGGER.info(
+                    '"%s": CHAT: language %s, finished sending message',
+                    self.api_wrapper.client.username, self.language
+                )
+            browser.close_current_tab()
+        else:
+            raise authentication_handler.NoLogginException()

+ 40 - 1
src/rival_regions_wrapper/api_wrapper/profile.py

@@ -1,10 +1,14 @@
 """Profile class"""
 
+import time
 import re
 
 from bs4 import BeautifulSoup
 
-from .abstract_wrapper import AbstractWrapper
+from rival_regions_wrapper import authentication_handler, LOGGER
+from rival_regions_wrapper.browser import Browser
+from rival_regions_wrapper.cookie_handler import CookieHandler
+from rival_regions_wrapper.api_wrapper.abstract_wrapper import AbstractWrapper
 
 
 class Profile(AbstractWrapper):
@@ -32,3 +36,38 @@ class Profile(AbstractWrapper):
             'endurance': int(perks[2].text),
         }
         return profile
+
+    @authentication_handler.session_handler
+    def message(self, message):
+        """send personal message"""
+        LOGGER.info(
+                '"%s" PM: user id %s',
+                self.api_wrapper.client.username, self.profile_id
+            )
+        if self.api_wrapper.client.session:
+            response = self.api_wrapper.client.session.get(
+                    "https://rivalregions.com/#overview"
+                )
+            self.api_wrapper.client.check_response(response)
+            browser = Browser(showWindow=self.api_wrapper.client.show_window)
+            browser.go_to('https://rivalregions.com/')
+            for cookie_name, value in \
+                    self.api_wrapper.client.session.cookies.get_dict().items():
+                browser.add_cookie(
+                        CookieHandler.create_cookie(cookie_name, None, value)
+                    )
+            browser.go_to(
+                    'https://rivalregions.com/#messages/{}'
+                    .format(self.profile_id)
+                )
+            browser.refresh()
+            time.sleep(2)
+            browser.type(message, id='message')
+            browser.click(id='chat_send')
+            LOGGER.info(
+                    '"%s" PM: user id %s, finished sending message',
+                    self.api_wrapper.client.username, self.profile_id
+                )
+            browser.close_current_tab()
+        else:
+            raise authentication_handler.NoLogginException()

+ 12 - 180
src/rival_regions_wrapper/authentication_handler.py

@@ -10,9 +10,8 @@ import requests
 import cfscrape
 
 from rival_regions_wrapper import LOGGER
-
-from .cookie_handler import CookieHandler
-from .browser import StealthBrowser as Browser
+from rival_regions_wrapper.cookie_handler import CookieHandler
+from rival_regions_wrapper.browser import Browser
 
 
 class RRClientException(Exception):
@@ -260,18 +259,14 @@ class AuthenticationHandler:
             params['c'] = self.var_c
 
         LOGGER.info(
-                '"%s" GET: "%s" var_c: %s', self.username, path, add_var_c
+                '"%s": GET: "%s" var_c: %s', self.username, path, add_var_c
             )
         if self.session:
             response = self.session.get(
                 url='https://rivalregions.com/{}'.format(path),
                 params=params
             )
-            if "Session expired, please, reload the page" \
-                    in response.text or \
-                    'window.location="https://rivalregions.com";' \
-                    in response.text:
-                raise SessionExpireException()
+            self.check_response(response)
         else:
             raise NoLogginException()
         return response.text
@@ -285,183 +280,20 @@ class AuthenticationHandler:
             data = {}
         data['c'] = self.var_c
 
-        LOGGER.info('"%s" POST: "%s"', self.username, path)
+        LOGGER.info('"%s": POST: "%s"', self.username, path)
         if self.session:
             response = self.session.post(
                 "https://rivalregions.com/{}".format(path),
                 data=data
             )
-            if "Session expired, please, reload the page" \
-                    in response.text or \
-                    'window.location="https://rivalregions.com";' \
-                    in response.text:
-                raise SessionExpireException()
+            self.check_response(response)
         else:
             raise NoLogginException()
         return response.text
 
-    @session_handler
-    def send_chat(self, language, message):
-        """send chat message"""
-        LOGGER.info('"%s" CHAT: language %s', self.username, language)
-        if self.session:
-            response = self.session.get("https://rivalregions.com/#overview")
-            if "Session expired, please, reload the page" in response.text:
-                raise SessionExpireException()
-            browser = Browser(showWindow=self.show_window)
-            browser.go_to('https://rivalregions.com/')
-            for cookie in CookieHandler.get_cookies(self.username):
-                browser.add_cookie(cookie)
-            browser.go_to(
-                    'https://rivalregions.com/#slide/chat/lang_{}'
-                    .format(language)
-                )
-            browser.refresh()
-            time.sleep(2)
-            browser.type(message, id='message')
-            browser.click(id='chat_send')
-            LOGGER.info(
-                '"%s" CHAT: language %s, finished sending message',
-                self.username, language
-            )
-            browser.close_current_tab()
-        else:
-            raise NoLogginException()
-
-    @session_handler
-    def send_personal_message(self, user_id, message):
-        """send personal message"""
-        LOGGER.info('"%s" PM: user id %s', self.username, user_id)
-        if self.session:
-            response = self.session.get("https://rivalregions.com/#overview")
-            if "Session expired, please, reload the page" in response.text:
-                raise SessionExpireException()
-            browser = Browser(showWindow=self.show_window)
-            browser.go_to('https://rivalregions.com/')
-            for cookie in CookieHandler.get_cookies(self.username):
-                browser.add_cookie(cookie)
-            browser.go_to(
-                    'https://rivalregions.com/#messages/{}'.format(user_id)
-                )
-            browser.refresh()
-            time.sleep(2)
-            browser.type(message, id='message')
-            browser.click(id='chat_send')
-            LOGGER.info(
-                    '"%s" PM: user id %s, finished sending message',
-                    self.username, user_id)
-            browser.close_current_tab()
-        else:
-            raise NoLogginException()
-
-    @session_handler
-    def send_conference_message(self, conference_id, message):
-        """send conference message"""
-        LOGGER.info(
-                '"%s": CONF "%s": send message',
-                self.username, conference_id
-            )
-        if self.session:
-            response = self.session.get("https://rivalregions.com/#overview")
-            if "Session expired, please, reload the page" in response.text:
-                raise SessionExpireException()
-            browser = Browser(showWindow=self.show_window)
-            browser.go_to('https://rivalregions.com/')
-            for cookie_name, value in self.session.cookies.get_dict().items():
-                browser.add_cookie(
-                    CookieHandler.create_cookie(cookie_name, None, value)
-                )
-            browser.go_to(
-                    'https://rivalregions.com/#slide/conference/{}'
-                    .format(conference_id)
-                )
-            browser.refresh()
-            time.sleep(2)
-
-            character_count = 0
-            tmp_messages = []
-            for sentence in message.split('\n'):
-                sentence_character_count = 0
-                tmp_sentence = []
-                for word in sentence.split(' '):
-                    sentence_character_count += len(word) + 1
-                    if sentence_character_count >= 899:
-                        message = '{}\n{}'.format('\n'.join(
-                                tmp_messages),
-                                ' '.join(tmp_sentence)
-                            )
-                        LOGGER.info(
-                                '"%s": CONF "%s": next message length: %s',
-                                self.username, conference_id, len(message)
-                            )
-                        browser.type(message, id='message')
-                        browser.click(id='chat_send')
-                        sentence_character_count = 0
-                        tmp_sentence = []
-                        character_count = 0
-                        tmp_messages = []
-                    tmp_sentence.append(word)
-
-                sentence = ' '.join(tmp_sentence)
-                character_count += len(sentence) + 1
-                if character_count >= 900:
-                    message = '\n'.join(tmp_messages)
-                    LOGGER.info(
-                        'conference %s: next message length: %s',
-                        conference_id, len(message)
-                    )
-                    browser.type(message, id='message')
-                    browser.click(id='chat_send')
-                    character_count = 0
-                    tmp_messages = []
-                tmp_messages.append(sentence)
-
-            if tmp_messages:
-                message = '\n'.join(tmp_messages)
-                LOGGER.info(
-                        '"%s": CONF "%s": next message length: %s',
-                        self.username, conference_id, len(message)
-                    )
-                browser.type(message, id='message')
-                browser.click(id='chat_send')
-
-            LOGGER.info(
-                    '"%s": CONF "%s": finished sending message',
-                    self.username, conference_id
-                )
-            browser.close_current_tab()
-        else:
-            raise NoLogginException()
-
-    @session_handler
-    def send_conference_notification(self, conference_id, message, sound):
-        """send conference notification"""
-        LOGGER.info(
-                '"%s": CONF: %s notification',
-                self.username, conference_id
-            )
-        data = {
-            'sound': 1 if sound else 0,
-            'text': message,
-            'c': self.var_c
-        }
-
-        if self.session:
-            response = self.session.post(
-                "https://rivalregions.com/rival/konffcm/{}/".format(
-                    conference_id
-                ),
-                data=data
-            )
-            if "Session expired, please, reload the page" \
-                    in response.text or \
-                    'window.location="https://rivalregions.com";' \
-                    in response.text:
-                raise SessionExpireException()
-        else:
-            raise NoLogginException()
-        LOGGER.info(
-                '"%s" CONF: id %s send notification ',
-                self.username, conference_id
-            )
-        return response.text
+    @classmethod
+    def check_response(cls, response):
+        """Check resonse for authentication"""
+        if "Session expired, please, reload the page" in response.text or \
+                'window.location="https://rivalregions.com";' in response.text:
+            raise SessionExpireException()

+ 10 - 2
src/rival_regions_wrapper/browser.py

@@ -8,10 +8,10 @@ import errno
 from selenium_stealth import stealth
 from selenium import webdriver
 from selenium.webdriver.common.keys import Keys
-from webbot import Browser
+import webbot
 
 
-class StealthBrowser(Browser):
+class Browser(webbot.Browser):
     """
     **Constructor**
 
@@ -93,3 +93,11 @@ class StealthBrowser(Browser):
                     'start_session', 'stop_client', 'switch_to_alert'
                 ]:
             setattr(self, function, getattr(self.driver, function))
+
+    def add_cookie(self, cookie):
+        """To pretent lint error"""
+        self.add_cookie(cookie)
+
+    def refresh(self):
+        """To pretent lint error"""
+        self.refresh()

+ 1 - 15
src/rival_regions_wrapper/middleware.py

@@ -4,7 +4,7 @@ from abc import ABC, abstractmethod
 
 import requests
 
-from rival_regions_wrapper import AuthenticationHandler
+from rival_regions_wrapper.authentication_handler import AuthenticationHandler
 
 
 class MiddlewareBase(ABC):
@@ -18,13 +18,6 @@ class MiddlewareBase(ABC):
     def post(self, path, data=None):
         """Send post request"""
 
-    @abstractmethod
-    def send_conference_message(self, conference_id, message):
-        """Send conference message"""
-
-    @abstractmethod
-    def send_conference_notification(self, conference_id, message, sound):
-        """Send conference notification"""
 
 class LocalAuthentication(MiddlewareBase):
     """Local authentication"""
@@ -46,13 +39,6 @@ class LocalAuthentication(MiddlewareBase):
         """Send post request"""
         return self.client.post(path, data=data)
 
-    def send_conference_message(self, conference_id, message):
-        """Send conference message"""
-        return self.client.send_conference_message(conference_id, message)
-
-    def send_conference_notification(self, conference_id, message, sound):
-        """Send conference notification"""
-        return self.client.send_conference_notification(conference_id, message, sound)
 
 class RemoteAuthentication(MiddlewareBase):
     """Remote authentication"""

+ 1 - 1
tests/conftest.py

@@ -5,7 +5,7 @@ import os
 import pytest
 from dotenv import load_dotenv
 
-from rival_regions_wrapper import LocalAuthentication
+from rival_regions_wrapper.middleware import LocalAuthentication
 
 
 load_dotenv()

+ 234 - 92
tests/test_rival_regions_wrapper.py

@@ -1,17 +1,23 @@
 """Wrapper test"""
 
+# pylint: disable=redefined-outer-name
+
 from datetime import datetime, timedelta
 
 import pytest
 
-from rival_regions_wrapper.api_wrapper import Profile, Storage, Market, ResourceState, Perks, \
-    Craft, Overview, War, Work, Article, Conference
+from rival_regions_wrapper.api_wrapper import Profile, Storage, Market, \
+        ResourceState, Perks, Craft, Overview, War, Work, Article, Conference
 
 
 @pytest.fixture
 def profile_keys():
     """Standard key from profile"""
-    return ['profile_id', 'name', 'level', 'level_percentage', 'strenght', 'education', 'endurance']
+    return [
+            'profile_id', 'name', 'level', 'level_percentage', 'strenght',
+            'education', 'endurance'
+        ]
+
 
 @pytest.mark.vcr()
 def test_profile_info(api_wrapper, profile_keys):
@@ -20,28 +26,41 @@ def test_profile_info(api_wrapper, profile_keys):
     response = profile_instance.info()
 
     assert isinstance(response, dict), "The response should be a dict"
-    assert response['profile_id'] == 192852686, "The ID should be in the response"
-    assert set(profile_keys).issubset(response.keys()), "All keys should be in the response"
+    assert response['profile_id'] == 192852686, \
+        "The ID should be in the response"
+    assert set(profile_keys).issubset(response.keys()), \
+        "All keys should be in the response"
     assert isinstance(response['name'], str), "Name should be a string"
     assert isinstance(response['level'], int), "level should be a int"
-    assert isinstance(response['level_percentage'], int), "level_percentage should be a int"
+    assert isinstance(response['level_percentage'], int), \
+        "level_percentage should be a int"
     assert isinstance(response['strenght'], int), "strenght should be a int"
     assert isinstance(response['education'], int), "education should be a int"
     assert isinstance(response['endurance'], int), "endurance should be a int"
 
+
+@pytest.mark.skip(reason="message request")
+def test_profile_message(api_wrapper):
+    """Test an API to send message to profile"""
+    Profile(api_wrapper, 2000340574).message('hi')
+
+
 @pytest.fixture
 def storage_keys():
     """Standard keys for storage"""
     return [
-        'oil', 'ore', 'uranium', 'diamonds', 'liquid_oxygen',
-        'helium-3', 'rivalium', 'antirad', 'energy_drink',
-        'spacerockets', 'lss', 'tanks', 'aircrafts', 'missiles',
-        'bombers', 'battleships', 'laser_drones', 'moon_tanks', 'space_stations',
-        'oil_max', 'ore_max', 'uranium_max', 'diamonds_max', 'liquid_oxygen_max',
-        'helium-3_max', 'rivalium_max', 'antirad_max', 'energy_drink_max',
-        'spacerockets_max', 'lss_max', 'tanks_max', 'aircrafts_max', 'missiles_max',
-        'bombers_max', 'battleships_max', 'laser_drones_max', 'moon_tanks_max', 'space_stations'
-    ]
+            'oil', 'ore', 'uranium', 'diamonds', 'liquid_oxygen',
+            'helium-3', 'rivalium', 'antirad', 'energy_drink',
+            'spacerockets', 'lss', 'tanks', 'aircrafts', 'missiles',
+            'bombers', 'battleships', 'laser_drones', 'moon_tanks',
+            'space_stations', 'oil_max', 'ore_max', 'uranium_max',
+            'diamonds_max', 'liquid_oxygen_max', 'helium-3_max',
+            'rivalium_max', 'antirad_max', 'energy_drink_max',
+            'spacerockets_max', 'lss_max', 'tanks_max', 'aircrafts_max',
+            'missiles_max', 'bombers_max', 'battleships_max',
+            'laser_drones_max', 'moon_tanks_max', 'space_stations'
+        ]
+
 
 @pytest.mark.vcr()
 def test_storage_info(api_wrapper, storage_keys):
@@ -49,13 +68,16 @@ def test_storage_info(api_wrapper, storage_keys):
     response = Storage(api_wrapper).info()
 
     assert isinstance(response, dict), "The response should be a dict"
-    assert set(storage_keys).issubset(response.keys()), "All keys should be in the response"
+    assert set(storage_keys).issubset(response.keys()), \
+        "All keys should be in the response"
+
 
 @pytest.fixture
 def market_keys():
     """Standard keys for storage"""
     return ['player_id', 'player_name', 'price', 'amount']
 
+
 @pytest.mark.vcr()
 def test_market_info(api_wrapper, market_keys):
     """Test an API call to get market info"""
@@ -64,17 +86,28 @@ def test_market_info(api_wrapper, market_keys):
 
     assert isinstance(response, list), "The response should be a list"
     if response:
-        assert isinstance(response[0], dict), "The first element should be a dict"
-        assert set(market_keys).issubset(response[0].keys()), "All keys should be in the response"
-        assert isinstance(response[0]['player_id'], int), "The player_id should be a int"
-        assert isinstance(response[0]['player_name'], str), "The player_name should be a int"
-        assert isinstance(response[0]['price'], int), "The price should be a int"
-        assert isinstance(response[0]['amount'], int), "The price should be a int"
+        assert isinstance(response[0], dict), \
+            "The first element should be a dict"
+        assert set(market_keys).issubset(response[0].keys()), \
+            "All keys should be in the response"
+        assert isinstance(response[0]['player_id'], int), \
+            "The player_id should be a int"
+        assert isinstance(response[0]['player_name'], str), \
+            "The player_name should be a int"
+        assert isinstance(response[0]['price'], int), \
+            "The price should be a int"
+        assert isinstance(response[0]['amount'], int), \
+            "The price should be a int"
+
 
 @pytest.fixture
 def resource_keys():
     """Standard keys for resource"""
-    return ['region_id', 'region_name', 'explored', 'maximum', 'deep_exploration', 'limit_left']
+    return [
+            'region_id', 'region_name', 'explored', 'maximum',
+            'deep_exploration', 'limit_left'
+        ]
+
 
 @pytest.mark.vcr()
 def test_resource_state_info(api_wrapper, resource_keys):
@@ -85,37 +118,56 @@ def test_resource_state_info(api_wrapper, resource_keys):
 
     assert isinstance(response, list), "The response should be a list"
     if response:
-        assert isinstance(response[0], dict), "The first element should be a dict"
-        assert set(resource_keys).issubset(response[0].keys()), "All keys should be in the response"
-        assert isinstance(response[0]['region_id'], int), "The region_id should be a int"
-        assert isinstance(response[0]['region_name'], str), "The region_name should be a str"
-        assert isinstance(response[0]['explored'], float), "The explored should be a float"
-        assert isinstance(response[0]['maximum'], int), "The maximum should be a int"
-        assert isinstance(response[0]['deep_exploration'], int), "deep_exploration should be int"
-        assert isinstance(response[0]['limit_left'], int), "The limit_left should be a int"
+        assert isinstance(response[0], dict), \
+            "The first element should be a dict"
+        assert set(resource_keys).issubset(response[0].keys()), \
+            "All keys should be in the response"
+        assert isinstance(response[0]['region_id'], int), \
+            "The region_id should be a int"
+        assert isinstance(response[0]['region_name'], str), \
+            "The region_name should be a str"
+        assert isinstance(response[0]['explored'], float), \
+            "The explored should be a float"
+        assert isinstance(response[0]['maximum'], int), \
+            "The maximum should be a int"
+        assert isinstance(response[0]['deep_exploration'], int), \
+            "deep_exploration should be int"
+        assert isinstance(response[0]['limit_left'], int), \
+            "The limit_left should be a int"
+
 
 @pytest.fixture
 def perks_keys():
     """Standard keys for perks"""
-    return ['strenght', 'education', 'endurance', 'upgrade_date', 'upgrade_perk']
+    return [
+            'strenght', 'education', 'endurance', 'upgrade_date',
+            'upgrade_perk'
+        ]
+
 
 @pytest.mark.vcr()
 def test_perks_info(api_wrapper, perks_keys):
     """Test an API call to get perks info"""
     response = Perks(api_wrapper).info()
 
-    assert isinstance(response, dict), "The response should be a dict"
-    assert set(perks_keys).issubset(response.keys()), "All keys should be in the response"
+    assert isinstance(response, dict), \
+        "The response should be a dict"
+    assert set(perks_keys).issubset(response.keys()), \
+        "All keys should be in the response"
     assert isinstance(response['strenght'], int), "strengt should be an int"
     assert isinstance(response['education'], int), "educatino should be an int"
     assert isinstance(response['endurance'], int), "endurance should be an int"
 
     try:
-        assert isinstance(response['upgrade_date'], datetime), "upgrade_date should be a date"
-        assert isinstance(response['upgrade_perk'], int), "upgrade_perk should be an int"
+        assert isinstance(response['upgrade_date'], datetime), \
+            "upgrade_date should be a date"
+        assert isinstance(response['upgrade_perk'], int), \
+            "upgrade_perk should be an int"
     except AssertionError:
-        assert isinstance(response['upgrade_date'], type(None)), "upgrade_date should be None if not upgrading"
-        assert isinstance(response['upgrade_perk'], type(None)), "upgrade_perk should be an int"
+        assert isinstance(response['upgrade_date'], type(None)), \
+            "upgrade_date should be None if not upgrading"
+        assert isinstance(response['upgrade_perk'], type(None)), \
+            "upgrade_perk should be an int"
 
 
 @pytest.mark.skip(reason="Update request")
@@ -123,13 +175,15 @@ def test_perks_upgrade(api_wrapper):
     """Test an API call to upgrade perk"""
     perk = 'endurance'
     upgrade_type = 'money'
-    Perks.upgrade(perk, upgrade_type)
+    Perks(api_wrapper).upgrade(perk, upgrade_type)
+
 
 @pytest.fixture
 def craft_keys():
     """Standard keys for craft"""
     return ['market_price', 'resources']
 
+
 @pytest.mark.skip(reason="Update request")
 def test_craft_produce(api_wrapper):
     """Test an API call to produce new item"""
@@ -138,24 +192,31 @@ def test_craft_produce(api_wrapper):
 
     assert True
 
+
 @pytest.fixture
 def overview_info_keys():
     """Standard keys for overview info"""
     return ['perks', 'war']
 
+
 @pytest.mark.vcr()
 def test_overview_info(api_wrapper, overview_info_keys):
     """Test an API call for overview"""
     response = Overview(api_wrapper).info()
 
     assert isinstance(response, dict), "The response hould be a dict"
-    assert set(overview_info_keys).issubset(response.keys()), "All keys should be in the response"
+    assert set(overview_info_keys).issubset(response.keys()), \
+        "All keys should be in the response"
     assert isinstance(response['war'], dict), "The war key should be a dict"
 
+
 @pytest.fixture
 def overview_status_keys():
     """Standard kenys for overview status"""
-    return ['profile_id', 'party_id', 'gold', 'money', 'level', 'exp']
+    return [
+            'profile_id', 'party_id', 'gold', 'money', 'level', 'exp'
+        ]
+
 
 @pytest.mark.vcr()
 def test_overview_status(api_wrapper, overview_status_keys):
@@ -163,7 +224,9 @@ def test_overview_status(api_wrapper, overview_status_keys):
     response = Overview(api_wrapper).status()
 
     assert isinstance(response, dict), "The response hould be a dict"
-    assert set(overview_status_keys).issubset(response.keys()), "All keys should be in the response"
+    assert set(overview_status_keys).issubset(response.keys()), \
+        "All keys should be in the response"
+
 
 @pytest.mark.vcr()
 def test_war_page(api_wrapper):
@@ -172,7 +235,9 @@ def test_war_page(api_wrapper):
 
     assert isinstance(response, dict), "The response should be a dict"
     if response['training_war']:
-        assert isinstance(response['training_war'], int), "The training_war should be an int"
+        assert isinstance(response['training_war'], int), \
+            "The training_war should be an int"
+
 
 @pytest.mark.vcr()
 def test_war_info(api_wrapper):
@@ -183,17 +248,26 @@ def test_war_info(api_wrapper):
     response = war.info(war_id)
 
     assert isinstance(response, dict), "The response should be a dict"
-    assert isinstance(response['damage'], int), "Damage should be an int"
-    assert isinstance(response['attack_hourly_available'], bool), "Attack hourly should be a bool"
-    assert isinstance(response['energ_drinks'], int), "Energy drinks should be an int"
+    assert isinstance(response['damage'], int), \
+        "Damage should be an int"
+    assert isinstance(response['attack_hourly_available'], bool), \
+        "Attack hourly should be a bool"
+    assert isinstance(response['energ_drinks'], int), \
+        "Energy drinks should be an int"
     if 'max_hero_name' in response:
-        assert isinstance(response['max_hero_name'], str), "max hero name should be a str"
+        assert isinstance(response['max_hero_name'], str), \
+            "max hero name should be a str"
     if 'max_hero_damage' in response:
-        assert isinstance(response['max_hero_damage'], int), "max hero damage should be an int"
+        assert isinstance(response['max_hero_damage'], int), \
+            "max hero damage should be an int"
     if 'time_left' in response:
-        assert isinstance(response['time_left'], timedelta), "time left should be a time delta"
-    assert isinstance(response['finish_date'], datetime), "Finish date should be a date"
-    assert isinstance(response['war_units'], dict), "war units should be a dict"
+        assert isinstance(response['time_left'], timedelta), \
+            "time left should be a time delta"
+    assert isinstance(response['finish_date'], datetime), \
+        "Finish date should be a date"
+    assert isinstance(response['war_units'], dict), \
+        "war units should be a dict"
+
 
 @pytest.mark.vcr()
 def test_war_info_ground_war(api_wrapper):
@@ -204,16 +278,27 @@ def test_war_info_ground_war(api_wrapper):
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'war', "Type should be a ground war"
     assert isinstance(response['attack'], dict), "Attack should be a dict"
-    assert isinstance(response['attack']['state_id'], int), "State id should be an integer"
-    assert isinstance(response['attack']['state_name'], str), "State nameshould be a string"
-    assert isinstance(response['attack']['region_id'], int), "Region id should be an integer"
-    assert isinstance(response['attack']['region_name'], str), "Region name should be a string"
-    assert isinstance(response['attack']['damage'], int), "Damage should be an intger"
-    assert isinstance(response['defend']['state_id'], int), "State id should be an integer"
-    assert isinstance(response['defend']['state_name'], str), "State name should be a string"
-    assert isinstance(response['defend']['region_id'], int), "Region id should be an integer"
-    assert isinstance(response['defend']['region_name'], str), "Region name should be a string"
-    assert isinstance(response['defend']['damage'], int), "Damage should be an integer"
+    assert isinstance(response['attack']['state_id'], int), \
+        "State id should be an integer"
+    assert isinstance(response['attack']['state_name'], str), \
+        "State nameshould be a string"
+    assert isinstance(response['attack']['region_id'], int), \
+        "Region id should be an integer"
+    assert isinstance(response['attack']['region_name'], str), \
+        "Region name should be a string"
+    assert isinstance(response['attack']['damage'], int), \
+        "Damage should be an intger"
+    assert isinstance(response['defend']['state_id'], int), \
+        "State id should be an integer"
+    assert isinstance(response['defend']['state_name'], str), \
+        "State name should be a string"
+    assert isinstance(response['defend']['region_id'], int), \
+        "Region id should be an integer"
+    assert isinstance(response['defend']['region_name'], str), \
+        "Region name should be a string"
+    assert isinstance(response['defend']['damage'], int), \
+        "Damage should be an integer"
+
 
 @pytest.mark.vcr()
 def test_war_info_coup(api_wrapper):
@@ -224,6 +309,7 @@ def test_war_info_coup(api_wrapper):
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'coup', "Type should be a coup"
 
+
 @pytest.mark.vcr()
 def test_war_info_revolution(api_wrapper):
     """Test war info"""
@@ -233,6 +319,7 @@ def test_war_info_revolution(api_wrapper):
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'revolution', "Type should be a revolution"
 
+
 @pytest.mark.vcr()
 def test_war_info_trooper_war(api_wrapper):
     """Test war info"""
@@ -242,6 +329,7 @@ def test_war_info_trooper_war(api_wrapper):
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'troopers war', "Type should be a trooper war"
 
+
 @pytest.mark.vcr()
 def test_war_info_sea_war(api_wrapper):
     """Test war info"""
@@ -251,6 +339,7 @@ def test_war_info_sea_war(api_wrapper):
     assert isinstance(response, dict), "The response should be a dict"
     assert response['type'] == 'sea war', "Type should be a sea war"
 
+
 @pytest.mark.vcr()
 def test_war_info_space_war(api_wrapper):
     """Test war info"""
@@ -268,15 +357,21 @@ def test_work_info(api_wrapper):
 
     assert isinstance(response, dict), "The response should be a dict"
     assert isinstance(response['factory'], dict), "Factory should be a dict"
-    assert isinstance(response['resources_left'], dict), "Resources left should be a dict"
+    assert isinstance(response['resources_left'], dict), \
+        "Resources left should be a dict"
     assert isinstance(response['work_exp'], dict), "Work exp should be a dict"
 
+
 @pytest.fixture
 def article_keys():
     """Standard key fro article"""
-    return ['article_id', 'article_title', 'newspaper_id', 'newspaper_name', \
-        'author_name', 'author_id', 'region_name', 'region_id', 'content_text', 'content_html', \
-        'language', 'rating', 'comments', 'post_date']
+    return [
+            'article_id', 'article_title', 'newspaper_id', 'newspaper_name',
+            'author_name', 'author_id', 'region_name', 'region_id',
+            'content_text', 'content_html', 'language', 'rating', 'comments',
+            'post_date'
+        ]
+
 
 @pytest.mark.vcr()
 def test_article_info_one(api_wrapper, article_keys):
@@ -285,21 +380,37 @@ def test_article_info_one(api_wrapper, article_keys):
     response = Article(api_wrapper).info(article_id)
 
     assert isinstance(response, dict), "The resonse should be a dict"
-    assert set(article_keys).issubset(response.keys()), "All keys should be in the response"
-    assert isinstance(response['article_id'], int), "Article id should be an integer"
-    assert isinstance(response['article_title'], str), "Article title should be a str"
-    assert isinstance(response['newspaper_id'], int), "Newspaper id should be an integer"
-    assert isinstance(response['newspaper_name'], str), "Newspaper name should be a string"
-    assert isinstance(response['author_name'], str), "Author name should be a string"
-    assert isinstance(response['author_id'], int), "Author id should be an integer"
-    assert isinstance(response['region_name'], str), "Region name should be a string"
-    assert isinstance(response['region_id'], int), "Region id should be an integer"
-    assert isinstance(response['content_text'], str), "Content text should be a string"
-    assert isinstance(response['content_html'], str), "Content html should be a string"
-    assert isinstance(response['language'], str), "Language should be a string"
-    assert isinstance(response['rating'], int), "Rating should be an integer"
-    assert isinstance(response['comments'], int), "Comments should be an integer"
-    assert isinstance(response['post_date'], datetime), "Post date should be a datetime"
+    assert set(article_keys).issubset(response.keys()), \
+        "All keys should be in the response"
+    assert isinstance(response['article_id'], int), \
+        "Article id should be an integer"
+    assert isinstance(response['article_title'], str), \
+        "Article title should be a str"
+    assert isinstance(response['newspaper_id'], int), \
+        "Newspaper id should be an integer"
+    assert isinstance(response['newspaper_name'], str), \
+        "Newspaper name should be a string"
+    assert isinstance(response['author_name'], str), \
+        "Author name should be a string"
+    assert isinstance(response['author_id'], int), \
+        "Author id should be an integer"
+    assert isinstance(response['region_name'], str), \
+        "Region name should be a string"
+    assert isinstance(response['region_id'], int), \
+        "Region id should be an integer"
+    assert isinstance(response['content_text'], str), \
+        "Content text should be a string"
+    assert isinstance(response['content_html'], str), \
+        "Content html should be a string"
+    assert isinstance(response['language'], str), \
+        "Language should be a string"
+    assert isinstance(response['rating'], int), \
+        "Rating should be an integer"
+    assert isinstance(response['comments'], int), \
+        "Comments should be an integer"
+    assert isinstance(response['post_date'], datetime), \
+        "Post date should be a datetime"
+
 
 @pytest.mark.vcr()
 def test_article_info_two(api_wrapper, article_keys):
@@ -308,25 +419,56 @@ def test_article_info_two(api_wrapper, article_keys):
     response = Article(api_wrapper).info(article_id)
 
     assert isinstance(response, dict), "The resonse should be a dict"
-    assert set(article_keys).issubset(response.keys()), "All keys should be in the response"
-    assert isinstance(response['article_id'], int), "Article id should be an integer"
-    assert isinstance(response['article_title'], str), "Article title should be a str"
+    assert set(article_keys).issubset(response.keys()), \
+        "All keys should be in the response"
+    assert isinstance(response['article_id'], int), \
+        "Article id should be an integer"
+    assert isinstance(response['article_title'], str), \
+        "Article title should be a str"
     assert response['newspaper_id'] is None, "Newspaper id should be none"
     assert response['newspaper_name'] is None, "Newspaper name should be none"
-    assert isinstance(response['author_name'], str), "Author name should be a string"
-    assert isinstance(response['author_id'], int), "Author id should be an integer"
-    assert isinstance(response['region_name'], str), "Region name should be a string"
-    assert isinstance(response['region_id'], int), "Region id should be an integer"
-    assert isinstance(response['content_text'], str), "Content text should be a string"
-    assert isinstance(response['content_html'], str), "Content html should be a string"
+    assert isinstance(response['author_name'], str), \
+        "Author name should be a string"
+    assert isinstance(response['author_id'], int), \
+        "Author id should be an integer"
+    assert isinstance(response['region_name'], str), \
+        "Region name should be a string"
+    assert isinstance(response['region_id'], int), \
+        "Region id should be an integer"
+    assert isinstance(response['content_text'], str), \
+        "Content text should be a string"
+    assert isinstance(response['content_html'], str), \
+        "Content html should be a string"
     assert isinstance(response['language'], str), "Language should be a string"
     assert isinstance(response['rating'], int), "Rating should be an integer"
-    assert isinstance(response['comments'], int), "Comments should be an integer"
-    assert isinstance(response['post_date'], datetime), "Post date should be a datetime"
+    assert isinstance(response['comments'], int), \
+        "Comments should be an integer"
+    assert isinstance(response['post_date'], datetime), \
+        "Post date should be a datetime"
+
 
 @pytest.mark.skip(reason="message request")
 def test_conference_message(api_wrapper):
     """Test conference message"""
     conference_id = 439289
-    response = Conference(api_wrapper).send_message(conference_id, 'hi')
+    Conference(api_wrapper, conference_id).message('hi')
+
+
+@pytest.mark.skip(reason="notification request")
+def test_conference_notification(api_wrapper):
+    """Test conference notification"""
+    conference_id = 439289
+    Conference(api_wrapper, conference_id).notification('hi', True)
 
+
+@pytest.mark.skip(reason="notification request")
+def test_conference_change_title(api_wrapper):
+    """Test conference change title"""
+    conference_id = 439289
+    Conference(api_wrapper, conference_id).change_title('new title')
+
+
+@pytest.mark.skip(reason="message request")
+def test_language_chat_(api_wrapper):
+    """Test an API to send message to profile"""
+    Profile(api_wrapper, 2000340574).message('hi')