Example #1
0
    def test_initialization(self):
        # An error is raised if SeriesLane is created with an empty string.
        pytest.raises(ValueError, SeriesLane, self._default_library, "")
        pytest.raises(ValueError, SeriesLane, self._default_library, None)

        work = self._work(language="spa", audience=[Classifier.AUDIENCE_CHILDREN])
        work_based_lane = WorkBasedLane(self._default_library, work)
        child = SeriesLane(
            self._default_library,
            "Alrighty Then",
            parent=work_based_lane,
            languages=["eng"],
            audiences=["another audience"],
        )

        # The series provided in the constructor is stored as .series.
        assert "Alrighty Then" == child.series

        # The SeriesLane is added as a child of its parent
        # WorkBasedLane -- something that doesn't happen by default.
        assert [child] == work_based_lane.children

        # As a side effect of that, this lane's audiences and
        # languages were changed to values consistent with its parent.
        assert [work_based_lane.source_audience] == child.audiences
        assert work_based_lane.languages == child.languages

        # If for some reason there's no audience for the work used as
        # a basis for the parent lane, the parent lane's audience
        # filter is used as a basis for the child lane's audience filter.
        work_based_lane.source_audience = None
        child = SeriesLane(self._default_library, "No Audience", parent=work_based_lane)
        assert work_based_lane.audiences == child.audiences
Example #2
0
    def test_append_child(self):
        """When a WorkBasedLane gets a child, its language and audience
        restrictions are propagated to the child.
        """
        work = self._work(
            with_license_pool=True, audience=Classifier.AUDIENCE_CHILDREN,
            language='spa'
        )

        def make_child():
            # Set up a WorkList with settings that contradict the
            # settings of the work we'll be using as the basis for our
            # WorkBasedLane.
            child = WorkList()
            child.initialize(
                self._default_library, 'sublane', languages=['eng'],
                audiences=[Classifier.AUDIENCE_ADULT]
            )
            return child
        child1, child2 = [make_child() for i in range(2)]

        # The WorkBasedLane's restrictions are propagated to children
        # passed in to the constructor.
        lane = WorkBasedLane(self._default_library, work, 'parent lane',
                             children=[child1])

        eq_(['spa'], child1.languages)
        eq_([Classifier.AUDIENCE_CHILDREN], child1.audiences)

        # It also happens when .append_child is called after the
        # constructor.
        lane.append_child(child2)
        eq_(['spa'], child2.languages)
        eq_([Classifier.AUDIENCE_CHILDREN], child2.audiences)
Example #3
0
    def test_default_children_list_not_reused(self):
        work = self._work()

        # By default, a WorkBasedLane has no children.
        lane1 = WorkBasedLane(self._default_library, work)
        assert [] == lane1.children

        # Add a child...
        lane1.children.append(object)

        # Another lane for the same work gets a different, empty list
        # of children. It doesn't reuse the first lane's list.
        lane2 = WorkBasedLane(self._default_library, work)
        assert [] == lane2.children
Example #4
0
    def test_initialization(self):
        # An error is raised if SeriesLane is created with an empty string.
        assert_raises(
            ValueError, SeriesLane, self._default_library, ''
        )
        assert_raises(
            ValueError, SeriesLane, self._default_library, None
        )

        work = self._work(
            language='spa', audience=[Classifier.AUDIENCE_CHILDREN]
        )
        work_based_lane = WorkBasedLane(self._default_library, work)
        child = SeriesLane(self._default_library, "Alrighty Then",
                           parent=work_based_lane, languages=['eng'],
                           audiences=['another audience'])

        # The series provided in the constructor is stored as .series.
        eq_("Alrighty Then", child.series)

        # The SeriesLane is added as a child of its parent
        # WorkBasedLane -- something that doesn't happen by default.
        eq_([child], work_based_lane.children)

        # As a side effect of that, this lane's audiences and
        # languages were changed to values consistent with its parent.
        eq_([work_based_lane.source_audience], child.audiences)
        eq_(work_based_lane.languages, child.languages)
Example #5
0
    def test_initialization_sets_appropriate_audiences(self):
        work = self._work(with_license_pool=True)

        work.audience = Classifier.AUDIENCE_CHILDREN
        children_lane = WorkBasedLane(self._default_library, work, "")
        assert [Classifier.AUDIENCE_CHILDREN] == children_lane.audiences

        work.audience = Classifier.AUDIENCE_YOUNG_ADULT
        ya_lane = WorkBasedLane(self._default_library, work, "")
        assert sorted(Classifier.AUDIENCES_JUVENILE) == sorted(ya_lane.audiences)

        work.audience = Classifier.AUDIENCE_ADULT
        adult_lane = WorkBasedLane(self._default_library, work, "")
        assert sorted(Classifier.AUDIENCES) == sorted(adult_lane.audiences)

        work.audience = Classifier.AUDIENCE_ADULTS_ONLY
        adults_only_lane = WorkBasedLane(self._default_library, work, "")
        assert sorted(Classifier.AUDIENCES) == sorted(adults_only_lane.audiences)
Example #6
0
    def test_accessible_to(self):
        # A lane based on a Work is accessible to a patron only if
        # the Work is age-appropriate for the patron.
        work = self._work()
        patron = self._patron()
        lane = WorkBasedLane(self._default_library, work)

        work.age_appropriate_for_patron = MagicMock(return_value=False)
        assert False == lane.accessible_to(patron)
        work.age_appropriate_for_patron.assert_called_once_with(patron)

        # If for whatever reason Work is not set, we just we say the Lane is
        # accessible -- but things probably won't work.
        lane.work = None
        assert True == lane.accessible_to(patron)

        # age_appropriate_for_patron wasn't called, since there was no
        # work.
        work.age_appropriate_for_patron.assert_called_once_with(patron)

        lane.work = work
        work.age_appropriate_for_patron = MagicMock(return_value=True)
        lane = WorkBasedLane(self._default_library, work)
        assert True == lane.accessible_to(patron)
        work.age_appropriate_for_patron.assert_called_once_with(patron)

        # The WorkList rules are still enforced -- for instance, a
        # patron from library B can't access any kind of WorkList from
        # library A.
        other_library_patron = self._patron(library=self._library())
        assert False == lane.accessible_to(other_library_patron)

        # age_appropriate_for_patron was never called with the new
        # patron -- the WorkList rules answered the question before we
        # got to that point.
        work.age_appropriate_for_patron.assert_called_once_with(patron)