Beispiel #1
0
    def test_place_is_required(self):
        """
        Some job titles (like an MP) are meaningless if there is no place
        associated with them.
        """

        # create position with no place
        position = models.Position(
            person=self.person,
            title=self.title,
        )
        position._set_sorting_dates()
        position.full_clean()

        # Change the title to require a place
        self.title.requires_place = True
        with self.assertRaises(exceptions.ValidationError):
            position.full_clean()

        # give the pos a place and check that it now validates
        position.place = models.Place(name='Test Place', slug='test-place')
        position.full_clean()

        # put it back
        self.title.requires_place = False
Beispiel #2
0
    def test_display_dates(self):
        """Check that the date that is displayed is correct"""
        position = models.Position(person=self.person)

        # Dates that will be used for testing
        past = ApproximateDate(past=True)
        y2000 = ApproximateDate(year=2000)
        y2100 = ApproximateDate(year=2100)
        future = ApproximateDate(future=True)

        # test grid: start, end, uot
        tests = (
            (None, None, ""),
            (None, past, "Ended"),
            (None, y2000, "Ended 2000"),
            (None, y2100, "Will end 2100"),
            (None, future, "Ongoing"),
            (past, None, "Started"),
            (past, past, "Ended"),
            (past, y2000, "Ended 2000"),
            (past, y2100, "Will end 2100"),
            (past, future, "Ongoing"),
            (y2000, None, "Started 2000"),
            (y2000, past, "Started 2000, now ended"),
            (y2000, y2000, "2000 → 2000"),
            (y2000, y2100, "2000 → 2100"),
            (y2000, future, "Started 2000"),
            (y2100, None, "Will start 2100"),
            (y2100, y2100, "2100 → 2100"),
            (y2100, future, "Will start 2100"),
            (future, None, "Not started yet"),
            (future, future, "Not started yet"),

            # These are impossible, but we don't validate against them. Best check something
            # sensible is returned. Might need if we ever do a site for Time Lords!
            (y2100, past, "Will start 2100, now ended"),
            (y2100, y2000, "2100 → 2000"),
            (future, past, "Ended"),
            (future, y2000, "Ended 2000"),
            (future, y2100, "Will end 2100"),
        )

        for start_date, end_date, expected in tests:
            position.start_date = start_date
            position.end_date = end_date
            actual = position.display_dates()
            self.assertEqual(
                actual, expected, "%s -> %s should be '%s', not '%s'" %
                (start_date, end_date, expected, actual))
Beispiel #3
0
    def test_election_position_has_number(self):
        """
        Positions on an election list must contain a number.
        """
        pos = models.Position(person=self.person,
                              organisation=self.election_list_da,
                              title=self.title)

        pos._set_sorting_dates()

        with self.assertRaises(exceptions.ValidationError):
            pos.full_clean()

        pos.title = self.first_candidate
        pos.full_clean()
Beispiel #4
0
    def test_have_at_least_one_attribute(self):
        """
        Positions must have a person, and at least one more attribute.
        Otherwise they don't mean anything
        """

        pos = models.Position(person=self.person, )

        # call this manually so that the validation does not get all confused
        # about it
        pos._set_sorting_dates()

        with self.assertRaises(exceptions.ValidationError):
            pos.full_clean()

        # If this does not blow up then it is OK
        pos.organisation = self.organisation
        pos.full_clean()
Beispiel #5
0
    def test_unicode(self):
        """Check that missing attributes don't crash"""

        position = models.Position(person=self.person, )
        self.assertEqual(str(position), 'Test Person (??? at ???)')
Beispiel #6
0
    def test_sorting(self):
        """Check that the sorting is as expected"""

        position_dates = [
            # start_date, end_date,
            (
                'future',
                'future',
            ),
            (
                'future',
                None,
            ),
            (
                '2002',
                'future',
            ),
            (
                '2001',
                'future',
            ),
            ('past', 'future'),
            (
                None,
                'future',
            ),
            (
                'future',
                '2010',
            ),
            (
                '2010',
                None,
            ),
            (
                '2002',
                '2010',
            ),
            (
                '2001',
                '2010',
            ),
            ('past', '2010'),
            (
                None,
                '2010',
            ),
            (
                'future',
                '2009',
            ),
            (
                '2009',
                None,
            ),
            (
                '2002',
                '2009',
            ),
            (
                '2001',
                '2009',
            ),
            ('past', '2009'),
            (
                None,
                '2009',
            ),
            (
                '2002',
                None,
            ),
            (
                '2001',
                None,
            ),
            ('future', 'past'),  # <-- this is nonsensical
            ('2010', 'past'),
            ('2009', 'past'),
            ('past', 'past'),
            (None, 'past'),
            ('past', None),
            (
                None,
                None,
            ),
        ]

        # create the positions, store the config in the notes and create a list to compare against
        position_expected_order = []
        positions_to_save = []

        def approx_date_from_entry(entry):
            if entry is None:
                return None
            if entry == 'future':
                return ApproximateDate(future=True)
            if entry == 'past':
                return ApproximateDate(past=True)
            return ApproximateDate(year=int(entry))

        for dates in position_dates:
            note = u"%s -> %s" % dates

            start_date = approx_date_from_entry(dates[0])
            end_date = approx_date_from_entry(dates[1])

            position_expected_order.append(note)
            positions_to_save.append(
                models.Position(
                    start_date=start_date,
                    end_date=end_date,
                    note=note,
                    person=self.person,
                ))

        # save all the positions, but shuffle them first
        random.shuffle(positions_to_save)
        for position in positions_to_save:
            position.save()

        # get all the positions from db and check that they are sorted correctly
        positions_from_db = self.person.position_set.all()
        position_actual_order = [p.note for p in positions_from_db]

        # print
        # print position_actual_order
        # print
        # print position_expected_order
        # print

        self.maxDiff = None
        self.assertEqual(position_expected_order, position_actual_order)
Beispiel #7
0
 def create_position(**kwargs):
     pos = models.Position(**kwargs)
     pos._set_sorting_dates()
     pos.full_clean(
     )  # needed as otherwise no validation occurs. Genius!
    def handle(self, **options):

        coalition_member_title, created = models.PositionTitle.objects.get_or_create(
            name="Coalition Member", slug="coalition-member")

        # get a list of all parties in a coalition
        coalition_party_slugs = [
            slug for slug in self.party_to_coalition_mapping.keys()
            if self.party_to_coalition_mapping[slug]
        ]

        # get all the parties representing those slugs
        coalition_parties = [
            models.Organisation.objects.get(slug=slug)
            for slug in coalition_party_slugs
        ]

        # get all the positions of people who are currently members of those parties
        coalition_member_positions = (models.Position.objects.all().filter(
            title__slug='member').filter(
                organisation__in=coalition_parties).currently_active())

        # get all current aspirant positions
        current_aspirant_positions = (
            models.Position.objects.all().current_aspirant_positions())

        # extract the people who are both members of a coalition party and currently an aspirant
        coalition_members = (models.Person.objects.all().filter(
            position__in=coalition_member_positions).filter(
                position__in=current_aspirant_positions).distinct())

        coalition_memberships_to_end = set(
            models.Position.objects.all().filter(
                title=coalition_member_title).filter(
                    organisation__kind__slug='coalition').filter(
                        person__in=coalition_members).currently_active())

        # for all the coalition members go through and ensure that they are linked to the coalition as well
        for member in coalition_members:
            for party in member.parties():
                coalition_slug = self.party_to_coalition_mapping.get(
                    party.slug)
                if coalition_slug:
                    coalition = models.Organisation.objects.get(
                        slug=coalition_slug)
                    position_parameters = {
                        'title': coalition_member_title,
                        'person': member,
                        'organisation': coalition,
                        'category': 'political'
                    }
                    positions = models.Position.objects.all().currently_active(
                    ).filter(**position_parameters)
                    if len(positions) > 1:
                        raise Exception, "Multiple positions matched %s" % (
                            position_parameters, )
                    elif len(positions) == 1:
                        # There's still a current position that represents this:
                        existing_position = positions[0]
                        # Make sure that its end date is 'future':
                        existing_position.end_date = 'future'
                        existing_position.save()
                        coalition_memberships_to_end.discard(existing_position)
                    else:
                        # Otherwise the position has to be created:
                        new_position = models.Position(start_date=str(
                            datetime.date.today()),
                                                       end_date='future',
                                                       **position_parameters)
                        new_position.save()

        # End any coalition memberships that are no longer correct:
        for position in coalition_memberships_to_end:
            position.end_date = str(datetime.date.today() -
                                    datetime.timedelta(days=1))
            position.save()