Skip to content

Commit

Permalink
Merge pull request #145 from bmos/windows-support
Browse files Browse the repository at this point in the history
Windows support
  • Loading branch information
bmos authored Jan 13, 2025
2 parents e4ffdf0 + 49ad065 commit 6402a7a
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 22 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
os: ["ubuntu-latest"]
python-version: ["3.11", "3.12", "3.13"]
os: ["ubuntu-latest", "windows-latest", "macos-latest"]

runs-on: ${{ matrix.os }}

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Getting Started / Setting Up Development Environment

To run this code, you'll need to have Python 3.9, 3.10, 3.11, or 3.12 installed on your machine. You'll also need to
To run this code, you'll need to have Python 3.11, 3.12 or 3.13 installed on your machine. You'll also need to
install the required packages by running the following commands from inside the project folder:

```shell
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "fg-forge-updater"
version = "1.3.1"
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.11"
license = { file = "LICENSE" }
authors = [{ name = "bmos", email = "wil.thieme@protonmail.com" }]
urls = { Repository = "https://github.com/bmos/fg_forge_updater" }
Expand Down Expand Up @@ -31,6 +31,7 @@ dev = [
"ruff==0.9.1",
"types-beautifulsoup4==4.12.0.20241020",
"types-Markdown==3.7.0.20241204",
"types-requests==2.32.0.20241016",
"types-seaborn==0.13.2.20250111"
]
github-actions = [
Expand Down
Empty file added src/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion src/forge_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait

from dropzone import DropzoneErrorHandling, add_file_to_dropzone
from src.dropzone import DropzoneErrorHandling, add_file_to_dropzone


class ForgeTransactionType(Enum):
Expand Down
6 changes: 3 additions & 3 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from dotenv import load_dotenv
from selenium import webdriver

import build_processing
from forge_api import ForgeItem, ForgeCredentials, ForgeURLs, ForgeReleaseChannel
from users_graph import graph_users
import src.build_processing as build_processing
from src.forge_api import ForgeItem, ForgeCredentials, ForgeURLs, ForgeReleaseChannel
from src.users_graph import graph_users

logging.basicConfig(level=logging.INFO, format="%(asctime)s : %(levelname)s : %(message)s")

Expand Down
9 changes: 6 additions & 3 deletions src/users_graph.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import tempfile
import urllib.request

import matplotlib.pyplot as plt
import pandas as pd
import requests
import seaborn as sns
from matplotlib import font_manager
from matplotlib import rcParams

with tempfile.NamedTemporaryFile() as tmp_font:
urllib.request.urlretrieve("https://github.com/google/fonts/raw/main/ofl/lexend/Lexend%5Bwght%5D.ttf?raw=true", tmp_font.name) # nosec B310
FONT_URL = "https://github.com/google/fonts/raw/main/ofl/lexend/Lexend%5Bwght%5D.ttf?raw=true"


with tempfile.NamedTemporaryFile(delete=False, suffix=".ttf") as tmp_font:
tmp_font.write(requests.get(FONT_URL).content)
font_manager.fontManager.addfont(tmp_font.name)
rcParams["font.family"] = "Lexend"

Expand Down
9 changes: 6 additions & 3 deletions tests/dropzone/test_add_file_to_dropzone.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pathlib import Path
from typing import Optional
from unittest.mock import MagicMock, call

import pytest
Expand Down Expand Up @@ -26,13 +27,14 @@ def mock_element() -> MagicMock:
return element


def find_element(by: str, value: str) -> MagicMock:
def find_element(by: str, value: str) -> Optional[MagicMock]:
"""Return a mock_element if the (by, value) pair isn't found in TEST_ELEMENTS"""
if (by, value) in TEST_ELEMENTS:
return mock_element()
return None


def find_elements(by, value) -> list[MagicMock]:
def find_elements(by, value) -> list[Optional[MagicMock]]:
"""Return two mock_elements if the (by, value) pair isn't found in TEST_ELEMENTS"""
element = find_element(by, value)
return [element, element]
Expand All @@ -55,10 +57,11 @@ def test_add_file_to_dropzone() -> None:
def test_add_file_to_dropzone_timeout() -> None:
"""Ensure that timeout is raised if progress bar is not found after attempt to add file"""

def find_element_unsuccessful(by: str, value: str) -> MagicMock:
def find_element_unsuccessful(by: str, value: str) -> Optional[MagicMock]:
"""Construct the WebElement mock object, but only if matching the first two definitions in TEST_ELEMENTS"""
if (by, value) in [TEST_ELEMENTS[0], TEST_ELEMENTS[1]]:
return mock_element()
return None

mock_driver = MagicMock(spec=webdriver.Chrome)
mock_driver.find_element.side_effect = find_element_unsuccessful
Expand Down
10 changes: 7 additions & 3 deletions tests/dropzone/test_dropzone_error_handling.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Optional
from unittest.mock import MagicMock

import pytest
Expand All @@ -19,12 +20,13 @@ def test_check_report_toast_error() -> None:
"""Ensure that toast errors raise an exception containing the error text"""
error_text = "Never send a boy to do a woman's job."

def find_element(by, value) -> MagicMock:
def find_element(by, value) -> Optional[MagicMock]:
"""Returns a mock WebElement for a toast error where all child elements have a return value containing the error text"""
if by == By.XPATH and value == "//*[@class='toast toast-error']":
element = mock_element()
element.find_element.return_value.text = error_text
return element
return None

mock_driver = MagicMock(spec=webdriver.Chrome)
mock_driver.find_element.side_effect = find_element
Expand All @@ -37,7 +39,7 @@ def find_element(by, value) -> MagicMock:
def test_check_report_dropzone_upload_error() -> None:
error_text = "We have no names, man. No names. We are nameless!"

def find_element(by, value) -> MagicMock:
def find_element(by, value) -> Optional[MagicMock]:
"""Returns a mock WebElement for a dropzone tooltip error or error message based on the (by, value) pairs"""
if by == By.CLASS_NAME and value == "dz-error-message":
element = mock_element()
Expand All @@ -48,6 +50,7 @@ def find_element(by, value) -> MagicMock:
element = mock_element()
element.get_attribute.return_value = error_text
return element
return None

mock_driver = MagicMock(spec=webdriver.Chrome)
mock_driver.find_element.side_effect = find_element
Expand All @@ -60,7 +63,7 @@ def find_element(by, value) -> MagicMock:
def test_check_report_upload_percentage() -> None:
error_text = r"File upload timed out at \d+%"

def find_element(by, value) -> MagicMock:
def find_element(by, value) -> Optional[MagicMock]:
"""Returns a mock WebElement with all css properties returning sizes in pixels depending on the (by, value) pairs"""
if by == By.CLASS_NAME and value == "dz-upload":
element = mock_element()
Expand All @@ -70,6 +73,7 @@ def find_element(by, value) -> MagicMock:
element = mock_element()
element.value_of_css_property.return_value = "80px"
return element
return None

mock_driver = MagicMock(spec=webdriver.Chrome)
mock_driver.find_element.side_effect = find_element
Expand Down
2 changes: 1 addition & 1 deletion tests/forge_api/forge_item/test_forge_item_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ def test_forge_item_creation() -> None:
assert item.item_id == item_string
assert item.timeout == timeout_string
with pytest.raises(FrozenInstanceError):
item.item_id = "7"
item.item_id = "7" # type: ignore[misc]
8 changes: 7 additions & 1 deletion tests/forge_api/forge_item/test_forge_item_login.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import os
import sys
from typing import Optional
from unittest.mock import MagicMock, call

import requestium
Expand Down Expand Up @@ -25,10 +28,11 @@ def mock_element() -> MagicMock:
return element


def find_element(by: str, value: str) -> MagicMock:
def find_element(by: str, value: str) -> Optional[MagicMock]:
"""Return a mock_element if the (by, value) pair isn't found in TEST_ELEMENTS"""
if (by, value) in TEST_CALLS:
return mock_element()
return None


def test_csrf_extraction() -> None:
Expand Down Expand Up @@ -61,4 +65,6 @@ def test_forge_item_login() -> None:
expected_find_element.append(call(By.XPATH, "//div[@class='blockrow restore']")) # login failure message
expected_find_element.append(call(By.XPATH, "//div[@class='blockrow restore']")) # login failure message
expected_find_element.append(call(By.XPATH, "//div[@class='blockrow restore']")) # login failure message
if os.name == "nt" and not sys.version_info.minor >= 13:
expected_find_element.append(call(By.XPATH, "//div[@class='blockrow restore']")) # login failure message
assert mock_session.driver.find_element.mock_calls == expected_find_element
2 changes: 1 addition & 1 deletion tests/forge_api/test_forge_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ def test_forge_credentials_creation() -> None:
assert creds.username == user_string
assert creds.password == user_pass
with pytest.raises(FrozenInstanceError):
creds.password = "god"
creds.password = "god" # type: ignore[misc]
2 changes: 1 addition & 1 deletion tests/forge_api/test_forge_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ def test_forge_urls() -> None:
assert urls.MANAGE_CRAFT == "https://forge.fantasygrounds.com/crafter/manage-craft"
assert urls.API_CRAFTER_ITEMS == "https://forge.fantasygrounds.com/api/crafter/items"
with pytest.raises(FrozenInstanceError):
urls.MANAGE_CRAFT = "https://www.ellingson-mineral.com/"
urls.MANAGE_CRAFT = "https://www.ellingson-mineral.com/" # type: ignore[misc]
2 changes: 1 addition & 1 deletion tests/main/test_construct_objects.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from pathlib import Path

from forge_api import ForgeItem, ForgeURLs
from src.forge_api import ForgeItem, ForgeURLs
from src.main import construct_objects


Expand Down

0 comments on commit 6402a7a

Please sign in to comment.