def test_unlock_all_hints_for_step_unlocks_all_hints_for_the_user(self): u = self.create_user() hint = TextHint(1, "activated") user_hint = UserHints(id=hint.id, user_id=u.id) db.session.add(user_hint) db.session.commit() new_hint = TextHint(2, "not activated") self.assertIsNone(UserHints.query.filter(UserHints.id == new_hint.id).first()) unlock_all_hints_for_step(1, u, WorkshopHints({1: [hint, new_hint]})) self.assertIsNotNone(UserHints.query.filter(UserHints.id == new_hint.id).first())
def get_active_hints(user: User, hints: WorkshopHints) -> typing.List[Hint]: """ Retrieves the hints that were already activated for this user and workshop step. :param user: The current user. :param hints: All available hints. :return: A list of hints. """ visible_hints = [hint.id for hint in user.hints] return list( filter(lambda h: h.id in visible_hints, hints.get_hints_for_step(user.workshop_step)))
def unlock_all_hints_for_step(current_step: int, user: User, hints: WorkshopHints) -> None: """ Unlocks all hints for a user on a certain step. :param current_step: The current step for the user :param user: The current user. :param hints: All available hints. :return: void. """ active_hints_current_step = [h.id for h in get_active_hints(user, hints)] for hint in hints.get_hints_for_step(current_step): if hint.id not in active_hints_current_step: user_hint = UserHints(id=hint.id, user_id=user.id) db.session.add(user_hint) db.session.commit()
def retrieve_next_hint(user: User, current_step: int, hints: WorkshopHints) -> typing.Optional[Hint]: """ Retrieves the next hint (if available) for the user and the current step. :param user: The current user. :param current_step: The current step for the user :param hints: All available hints. :return: A hint, or None when not found. """ used_hints = [hint.id for hint in user.hints] def filter_criterium(hint): return hint.id not in used_hints hints_for_step = list( filter(filter_criterium, hints.get_hints_for_step(current_step))) hints_for_step.sort(key=lambda h: h.id) return None if len(hints_for_step) == 0 else hints_for_step[0]
from passlib.apps import custom_app_context as pwd_context from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, Length from xhtml2pdf import pisa from hint import Hint, WorkshopHints app = flask.Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', '') app.config['SECRET_KEY'] = 'foo-bar' app.config['CSRF_SESSION_KEY'] = 'foo-bar' db = SQLAlchemy(app) workshop_hints = WorkshopHints() class User(db.Model): """ Represents a user in the database. """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32), unique=True) password = db.Column(db.String(255), nullable=False) workshop_step = db.Column(db.Integer, default=1, nullable=False) hints = relationship("UserHints", back_populates="user") def is_password_valid(self, password: str) -> bool: """ Checks if the entered password matches the stored hash.
def test_that_getting_hints_for_an_known_step_returns_an_empty_list(self): h = WorkshopHints() self.assertNotEqual(0, len(h.get_hints_for_step(GITHUB)))
def test_retrieve_next_hint_returns_the_first_hint(self): expected = TextHint(1, "foo") hints = WorkshopHints({1: [expected]}) user = User() self.assertEqual(expected, retrieve_next_hint(user, 1, hints))
def test_retrieve_next_hint_returns_nothing_if_no_hints_are_left(self): hints = WorkshopHints({1: []}) user = User() self.assertEqual(None, retrieve_next_hint(user, 1, hints))
def test_get_active_hints_returns_active_hints(self): u = User(workshop_step=2) u.hints = [UserHints(id=1), UserHints(id=2)] non_activated_hint = TextHint(1, "foo") activated_hint = TextHint(2, "foo") self.assertListEqual([activated_hint], get_active_hints(u, WorkshopHints({1: [non_activated_hint], 2: [activated_hint]})))
def test_get_active_hints_returns_no_active_hints_if_there_were_none_in_that_step(self): u = User(workshop_step=1) self.assertListEqual([], get_active_hints(u, WorkshopHints({})))
def test_get_active_hints_returns_no_active_hints_if_there_were_none_activated_yet(self): non_activated_hint = TextHint(1, "foo") hints_with_non_activated_hint = WorkshopHints({3: [non_activated_hint]}) u = User(workshop_step=3) self.assertListEqual([], get_active_hints(u, hints_with_non_activated_hint))