diff --git a/.coveragerc b/.coveragerc index b369f80b..975d1f83 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,8 @@ [run] source = ./ +plugins = + django_coverage_plugin omit = */migrations/* diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml new file mode 100644 index 00000000..6ed5d189 --- /dev/null +++ b/.github/workflows/django.yml @@ -0,0 +1,48 @@ +name: Django CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + env: + IMGUR_UPLOAD_CLIENT_ID: ${{ secrets.IMGUR_UPLOAD_CLIENT_ID }} + IMGUR_UPLOAD_CLIENT_SECRET: ${{ secrets.IMGUR_UPLOAD_CLIENT_SECRET }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + max-parallel: 1 + matrix: + python-version: [3.8] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Setup Chromedriver + run: | + wget https://chromedriver.storage.googleapis.com/2.36/chromedriver_linux64.zip + unzip chromedriver_linux64.zip + export PATH=$PATH:$(pwd) + chmod +x chromedriver + export PATH=$PATH:/usr/lib/chromium-browser/ + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install pycodestyle coverage coveralls django_coverage_plugin + pip install -r requirements.txt + python manage.py collectstatic --noinput + - name: Basic Checks + run: | + pycodestyle . --exclude=migrations,importer* + python manage.py check + python manage.py makemigrations --check --dry-run + - name: Run Tests + run: | + coverage run manage.py test --verbosity=2 + coveralls --service=github diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8f9da399..00000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: python -python: - "3.8" -cache: pip - -addons: - chrome: stable - -before_install: - - export LANGUAGE=en_GB.UTF-8 - -install: - - | - latest=$(wget -qO- https://chromedriver.storage.googleapis.com/LATEST_RELEASE) - wget https://chromedriver.storage.googleapis.com/$latest/chromedriver_linux64.zip - - unzip chromedriver_linux64.zip - - export PATH=$PATH:$(pwd) - - chmod +x chromedriver - - pip install -r requirements.txt - - pip install coveralls codeclimate-test-reporter pycodestyle - -before_script: - - export PATH=$PATH:/usr/lib/chromium-browser/ - - python manage.py collectstatic --noinput - -script: - - pycodestyle . --exclude=migrations,importer* - - python manage.py check - - python manage.py makemigrations --check --dry-run - - coverage run manage.py test --verbosity=2 - -after_success: - - coveralls - - codeclimate-test-reporter - -notifications: - webhooks: https://fathomless-fjord-24024.herokuapp.com/notify diff --git a/PyRIGS/settings.py b/PyRIGS/settings.py index 0983721b..0d4df3db 100644 --- a/PyRIGS/settings.py +++ b/PyRIGS/settings.py @@ -13,6 +13,7 @@ import os import raven import secrets import datetime +from envparse import env BASE_DIR = os.path.dirname(os.path.dirname(__file__)) @@ -20,15 +21,15 @@ BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ.get('SECRET_KEY') if os.environ.get( - 'SECRET_KEY') else 'gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e' +SECRET_KEY = env('SECRET_KEY', default='gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e') + # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = bool(int(os.environ.get('DEBUG'))) if os.environ.get('DEBUG') else True +DEBUG = env('DEBUG', cast=bool, default=True) -STAGING = bool(int(os.environ.get('STAGING'))) if os.environ.get('STAGING') else False +STAGING = env('STAGING', cast=bool, default=False) -CI = bool(int(os.environ.get('CI'))) if os.environ.get('CI') else False +CI = env('CI', cast=bool, default=False) ALLOWED_HOSTS = ['pyrigs.nottinghamtec.co.uk', 'rigs.nottinghamtec.co.uk', 'pyrigs.herokuapp.com'] @@ -174,10 +175,7 @@ else: } RAVEN_CONFIG = { - 'dsn': os.environ.get('RAVEN_DSN'), - # If you are using git, you can also automatically configure the - # release based on the git info. - # 'release': raven.fetch_git_sha(os.path.dirname(os.path.dirname(__file__))), + 'dsn': env('RAVEN_DSN', default=""), } # User system @@ -190,10 +188,8 @@ LOGOUT_URL = '/user/logout/' ACCOUNT_ACTIVATION_DAYS = 7 # reCAPTCHA settings -RECAPTCHA_PUBLIC_KEY = os.environ.get('RECAPTCHA_PUBLIC_KEY', - "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI") # If not set, use development key -RECAPTCHA_PRIVATE_KEY = os.environ.get('RECAPTCHA_PRIVATE_KEY', - "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe") # If not set, use development key +RECAPTCHA_PUBLIC_KEY = env('RECAPTCHA_PUBLIC_KEY', default="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI") # If not set, use development key +RECAPTCHA_PRIVATE_KEY = env('RECAPTCHA_PUBLIC_KEY', default="6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe") # If not set, use development key NOCAPTCHA = True SILENCED_SYSTEM_CHECKS = ['captcha.recaptcha_test_key_error'] @@ -202,13 +198,13 @@ SILENCED_SYSTEM_CHECKS = ['captcha.recaptcha_test_key_error'] EMAILER_TEST = False if not DEBUG or EMAILER_TEST: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - EMAIL_HOST = os.environ.get('EMAIL_HOST') - EMAIL_PORT = int(os.environ.get('EMAIL_PORT', 25)) - EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER') - EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD') - EMAIL_USE_TLS = bool(int(os.environ.get('EMAIL_USE_TLS', 0))) - EMAIL_USE_SSL = bool(int(os.environ.get('EMAIL_USE_SSL', 0))) - DEFAULT_FROM_EMAIL = os.environ.get('EMAIL_FROM') + EMAIL_HOST = env('EMAIL_HOST') + EMAIL_PORT = env('EMAIL_PORT', cast=int, default=25) + EMAIL_HOST_USER = env('EMAIL_HOST_USER') + EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD') + EMAIL_USE_TLS = env('EMAIL_USE_TLS', cast=bool, default=False) + EMAIL_USE_SSL = env('EMAIL_USE_SSL', cast=bool, default=False) + DEFAULT_FROM_EMAIL = env('EMAIL_FROM') else: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' @@ -267,10 +263,6 @@ USE_GRAVATAR = True TERMS_OF_HIRE_URL = "http://www.nottinghamtec.co.uk/terms.pdf" AUTHORISATION_NOTIFICATION_ADDRESS = 'productions@nottinghamtec.co.uk' -RISK_ASSESSMENT_URL = os.environ.get('RISK_ASSESSMENT_URL') if os.environ.get( - 'RISK_ASSESSMENT_URL') else "http://example.com" -RISK_ASSESSMENT_SECRET = os.environ.get('RISK_ASSESSMENT_SECRET') if os.environ.get( - 'RISK_ASSESSMENT_SECRET') else secrets.token_hex(15) -IMGUR_UPLOAD_CLIENT_ID = os.environ.get('IMGUR_UPLOAD_CLIENT_ID', '') -IMGUR_UPLOAD_CLIENT_SECRET = os.environ.get('IMGUR_UPLOAD_CLIENT_SECRET', '') +IMGUR_UPLOAD_CLIENT_ID = env('IMGUR_UPLOAD_CLIENT_ID', default="") +IMGUR_UPLOAD_CLIENT_SECRET = env('IMGUR_UPLOAD_CLIENT_SECRET', default="") diff --git a/PyRIGS/tests/base.py b/PyRIGS/tests/base.py index d8af4237..a0d4866d 100644 --- a/PyRIGS/tests/base.py +++ b/PyRIGS/tests/base.py @@ -24,10 +24,8 @@ def create_browser(): # No caching, please and thank you options.add_argument("--aggressive-cache-discard") options.add_argument("--disk-cache-size=0") - # God Save The Queen - options.add_argument("--lang=en_GB") options.add_argument("--headless") - if os.environ.get('CI', False): + if settings.CI: options.add_argument("--no-sandbox") driver = webdriver.Chrome(options=options) return driver diff --git a/PyRIGS/tests/regions.py b/PyRIGS/tests/regions.py index 0e2110bf..0da78857 100644 --- a/PyRIGS/tests/regions.py +++ b/PyRIGS/tests/regions.py @@ -1,5 +1,6 @@ from pypom import Region from django.utils import timezone +from django.conf import settings from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions from selenium.webdriver.remote.webelement import WebElement @@ -19,18 +20,22 @@ def parse_bool_from_string(string): else: return False -# 12-Hour vs 24-Hour Time. Affects widget display - def get_time_format(): # Default - time_format = "%H:%M" - # If system is 12hr - if timezone.now().strftime("%p"): - time_format = "%I:%M %p" + time_format = "%H%M" + if settings.CI: # The CI is American + time_format = "%I%M%p" return time_format +def get_date_format(): + date_format = "%d%m%Y" + if settings.CI: # And try as I might I can't stop it being so + date_format = "%m%d%Y" + return date_format + + class BootstrapSelectElement(Region): _main_button_locator = (By.CSS_SELECTOR, 'button.dropdown-toggle') _option_box_locator = (By.CSS_SELECTOR, 'ul.dropdown-menu') @@ -150,13 +155,13 @@ class DatePicker(Region): def set_value(self, value): self.root.clear() - self.root.send_keys(value.strftime("%d%m%Y")) + self.root.send_keys(value.strftime(get_date_format())) class TimePicker(Region): @property def value(self): - return datetime.datetime.strptime(self.root.get_attribute("value"), get_time_format()) + return datetime.datetime.strptime(self.root.get_attribute("value"), "%H:%M") def set_value(self, value): self.root.clear() @@ -166,12 +171,12 @@ class TimePicker(Region): class DateTimePicker(Region): @property def value(self): - return datetime.datetime.strptime(self.root.get_attribute("value"), "%Y-%m-%d " + get_time_format()) + return datetime.datetime.strptime(self.root.get_attribute("value"), "%Y-%m-%d %H:%M") def set_value(self, value): self.root.clear() - date = value.date().strftime("%d%m%Y") + date = value.date().strftime(get_date_format()) time = value.time().strftime(get_time_format()) self.root.send_keys(date) diff --git a/README.md b/README.md index 9d0a155c..bc54ab76 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # TEC PA & Lighting - PyRIGS # -[![Build Status](https://travis-ci.org/nottinghamtec/PyRIGS.svg?branch=master)](https://travis-ci.org/nottinghamtec/PyRIGS) +![Build Status](https://github.com/nottinghamtec/PyRIGS/workflows/Django%20CI/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/nottinghamtec/PyRIGS/badge.svg)](https://coveralls.io/github/nottinghamtec/PyRIGS) Welcome to TEC PA & Lighting's PyRIGS program. This is a reimplementation of the previous Rig Information Gathering System (RIGS) that was developed using Ruby on Rails. PyRIGS is our in house app for the centralisation of information on our events and now assets. diff --git a/assets/tests/test_assets.py b/assets/tests/test_assets.py index 957cf4b1..59031cf3 100644 --- a/assets/tests/test_assets.py +++ b/assets/tests/test_assets.py @@ -136,7 +136,7 @@ class TestAssetForm(AutoLoginTest): self.page.purchased_from_selector.set_option(self.supplier.name, True) self.page.purchase_price = "12.99" self.page.salvage_value = "99.12" - self.page.date_acquired = acquired = datetime.date(2020, 5, 20) + self.page.date_acquired = acquired = datetime.date(2020, 5, 2) self.page.parent_selector.toggle() self.assertTrue(self.page.parent_selector.is_open) diff --git a/requirements.txt b/requirements.txt index 9cf271de..0b0bd701 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,6 @@ certifi==2020.6.20 chardet==3.0.4 configparser==5.0.1 contextlib2==0.6.0.post1 -coverage==5.3 cssselect==1.1.0 cssutils==1.0.2 diff-match-patch==20200713 @@ -27,6 +26,7 @@ django-registration-redux==2.8 django-reversion==3.0.8 django-toolbelt==0.0.1 django-widget-tweaks==1.4.8 +envparse==0.2.0 env-tools==2.2.0 gunicorn==20.0.4 icalendar==4.0.7