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
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)
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
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)
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)
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)