Skip to content

Commit

Permalink
Merge pull request #4 from appsembler/omar/py3
Browse files Browse the repository at this point in the history
support for python 3.5/3.8 and django 2.2 + basic tests
  • Loading branch information
OmarIthawi authored Jan 6, 2021
2 parents 4989680 + cbd24d2 commit 712fd1f
Show file tree
Hide file tree
Showing 14 changed files with 174 additions and 32 deletions.
36 changes: 20 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
name: Python application
name: feedbackxblock

on:
push:
branches: [ master, main ]
branches: [master, main]
pull_request:
branches: [ master, main ]

jobs:
build:

runs-on: ubuntu-latest

test:
runs-on: ubuntu-18.04
strategy:
matrix:
python-version: [2.7, 3.5, 3.8]
tox-env:
- quality
- py
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.5
uses: actions/setup-python@v2
with:
python-version: 3.5
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install tox
- name: Test with tox
run: tox -e ${{ matrix.tox-env }}
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
*pyc
rate_xblock.egg-info
*~
*~
.coverage
.tox
*.egg-info
__pycache__
2 changes: 0 additions & 2 deletions feedback/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@
course resources, and to think and synthesize about their experience
in the course.
"""

from .feedback import FeedbackXBlock
13 changes: 7 additions & 6 deletions feedback/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

import cgi
import random

import pkg_resources
import six

from xblock.core import XBlock
from xblock.fields import Scope, Integer, String, List, Float
from xblock.fragment import Fragment
from web_fragments.fragment import Fragment


# We provide default text which is designed to elicit student thought. We'd
# like instructors to customize this to something highly structured (not
Expand All @@ -31,7 +32,7 @@
# Unicode alt faces are cute, but we do nulls instead for a11y.
ICON_SETS = {'face': [""]*5, # u"😁😊😐😞😭",
'num': u"12345",
'midface': [""]*5} #u"😞😐😊😐😞"}
'midface': [""]*5} # u"😞😐😊😐😞"}


@XBlock.needs('i18n')
Expand Down Expand Up @@ -264,9 +265,9 @@ def studio_view(self, context):
prompt = self.get_prompt(0)
for idx in range(len(prompt['scale_text'])):
prompt['likert{i}'.format(i=idx)] = prompt['scale_text'][idx]
frag = Fragment(unicode(html_str).format(**prompt))
frag = Fragment(six.text_type(html_str).format(**prompt))
js_str = self.resource_string("static/js/src/studio.js")
frag.add_javascript(unicode(js_str))
frag.add_javascript(six.text_type(js_str))
frag.initialize_js('FeedbackBlock',
{'icon_set': prompt['icon_set']})
return frag
Expand Down Expand Up @@ -304,7 +305,7 @@ def vote(self, data):
"""
# prompt_choice is initialized by student view.
# Ideally, we'd break this out into a function.
prompt = self.get_prompt(self.prompt_choice)
prompt = self.get_prompt(self.prompt_choice) # noqa

# Make sure we're initialized
self.init_vote_aggregate()
Expand Down
1 change: 0 additions & 1 deletion feedbacktests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
from .test_feedback import TestFeedback
27 changes: 27 additions & 0 deletions feedbacktests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import pytest
from mock import Mock

from workbench.runtime import WorkbenchRuntime
from xblock.fields import ScopeIds
from xblock.runtime import DictKeyValueStore, KvsFieldData

from feedback.feedback import FeedbackXBlock


def generate_scope_ids(runtime, block_type):
""" helper to generate scope IDs for an XBlock """
def_id = runtime.id_generator.create_definition(block_type)
usage_id = runtime.id_generator.create_usage(def_id)
return ScopeIds('user', block_type, def_id, usage_id)


@pytest.fixture
def feedback_xblock():
"""Feedback XBlock pytest fixture."""
runtime = WorkbenchRuntime()
key_store = DictKeyValueStore()
db_model = KvsFieldData(key_store)
ids = generate_scope_ids(runtime, 'feedback')
feedback_xblock = FeedbackXBlock(runtime, db_model, scope_ids=ids)
feedback_xblock.usage_id = Mock()
return feedback_xblock
6 changes: 2 additions & 4 deletions feedbacktests/test_feedback.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'''
Tests for the FeedbackXBlock.
Tests for the FeedbackXBlock that needs to run in Open edX.
'''

import json
import sys

from openedx.tests.xblock_integration.xblock_testcase import XBlockTestCase
import mock
Expand Down Expand Up @@ -31,7 +29,7 @@ def set_random(self, random_patch_value):


# pylint: disable=abstract-method
class TestFeedback(PatchRandomMixin, XBlockTestCase):
class FeedbackTestCase(PatchRandomMixin, XBlockTestCase):
"""
Basic tests for the FeedbackXBlock. We set up a page with two
of the block, make sure the page renders, toggle a few ratings,
Expand Down
52 changes: 52 additions & 0 deletions feedbacktests/test_feedback_unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Tests for the Feedback XBlock with heavy mocking.
"""

from mock import Mock


def test_template_content(feedback_xblock):
""" Test content of FeedbackXBlock's student view """
student_fragment = feedback_xblock.render('student_view', Mock())
assert 'feedback' in student_fragment.content


def test_studio_view(feedback_xblock):
""" Test content of FeedbackXBlock's author view """
student_fragment = feedback_xblock.render('studio_view', Mock())
assert 'feedback' in student_fragment.content


def test_studio_submit(feedback_xblock):
""" Test the FeedbackXBlock's save action """
request_body = b"""{
"display_name": "foo"
}"""
request = Mock(method='POST', body=request_body)
response = feedback_xblock.studio_submit(request)
assert response.status_code == 200 and {'result': 'success'} == response.json, response.json


def test_vote(feedback_xblock):
""" Test content of FeedbackXBlock's vote() method """
feedback_xblock.vote({'vote': 1})


def test_feedback_method(feedback_xblock):
""" Test content of FeedbackXBlock's feedback() method """
request_body = b"""{
"freeform": "yes",
"vote": 1
}"""
request = Mock(method='POST', body=request_body)
response = feedback_xblock.feedback(request)

expected_response_json = {
"aggregate": [0, 1, 0, 0, 0],
"freeform": "yes",
"response": "Thank you for your feedback!",
"success": True,
"vote": 1,
}

assert response.status_code == 200 and response.json == expected_response_json, response.json
Empty file added geckodriver.log
Empty file.
3 changes: 2 additions & 1 deletion makeicons/test_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import unittest
from bok_choy.web_app_test import WebAppTest
from pages import IconsPage
from .pages import IconsPage


class TestIcons(WebAppTest):
Expand All @@ -29,5 +29,6 @@ def test_page_existence(self):
self.assertScreenshot("#"+style+icon+str(i+1),
style+icon+str(i+1))


if __name__ == '__main__':
unittest.main()
25 changes: 25 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
bok-choy>=1.1.1

Django>=1.11,<2; python_version < '3'
Django>=2.2,<2.3; python_version >= '3'

django-pyfs>=2.2
flake8>=3.8.4
mock>=3.0.5

pytest==4.6.11; python_version < '3'
pytest>=6.1.2; python_version >= '3'

pytest-cov>=2.10.1

pytest-django>=3.10.0; python_version < '3'
pytest-django>=4.1.0; python_version >= '3'

six>=1.15.0

web-fragments>=0.3.2

XBlock==1.2.1; python_version < '3'
XBlock>=1.4.0; python_version >= '3'

xblock-sdk>=0.2.2
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def package_data(pkg, roots):
],
entry_points={
'xblock.v1': [
'feedback = feedback:FeedbackXBlock',
'feedback = feedback.feedback:FeedbackXBlock',
],
'xblock.test.v0': [
'feedbacktest = feedbacktests:TestFeedback',
Expand Down
7 changes: 7 additions & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Test settings for the Feedback XBlock.
"""

from workbench.settings import *

from django.conf.global_settings import LOGGING
26 changes: 26 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[tox]
envlist = py{27,35,38},quality
skipsdist = True

[pytest]
addopts = --cov=feedback --cov-report=term-missing

[testenv]
usedevelop=True
passenv =
SELENIUM_BROWSER
setenv =
DJANGO_SETTINGS_MODULE = test_settings
deps =
-r{toxinidir}/requirements.txt
commands =
# TODO: Activate the rest of the tests once they're fixed
{posargs:pytest feedbacktests/test_feedback_unit.py}

[flake8]
max-line-length = 160

[testenv:quality]
deps = flake8
commands =
flake8 feedback feedbacktests makeicons setup.py

0 comments on commit 712fd1f

Please sign in to comment.