'We check against three rules:
1) The aggregate record that matches the newly inserted record
* Use indicator and location to find the record. It should
have a type of 1 for the actual period other periods will
have types of 1 or 3, and the data may vary
2) The records aggregate for each parent location
* The type will be 2 but the data may vary
3) The records for the indicator for each location and time period
* The type will be 4 but the data may vary'

def validateAggregateData(self, step, actual_date, indicator_id, location_id, expected):

    from dateutil.rrule import rrule, YEARLY
    db = current.db
    s3db = current.s3db
    aggregated_period = s3db.vulnerability_aggregated_period
    (first_period, dummy) = aggregated_period(actual_date)
    (last_period, dummy) = aggregated_period()
    atable = db.vulnerability_aggregate
    fields = [atable.agg_type, atable.reported_count, atable.ward_count, atable.date, atable.location_id, atable.max, atable.min, atable.mean, atable.median]
    query = (((atable.parameter_id == indicator_id) & (atable.location_id == location_id)) & (atable.deleted == False))
    rows = db(query).select(*fields)
    aggr_data = {}
    for row in rows:
        aggr_data[row.date] = row
    for dt in rrule(YEARLY, dtstart=first_period, until=last_period):
        dt = dt.date()
        msg = ('Step    %s,    Rule    1:    Failed    to    find    an    aggregate    record    starting    with    date    %s' % (step, dt))
        self.assertTrue((dt in aggr_data), msg)
        record = aggr_data[dt]
        if (dt in expected.rule1.type):
            exp_type = expected.rule1.type[dt]
            last_exp_type = exp_type
        else:
            exp_type = last_exp_type
        if (dt in expected.rule1.data):
            exp_data = expected.rule1.data[dt]
            last_exp_data = exp_data
        else:
            exp_data = last_exp_data
        msg = ('Step    %s,    Rule    1:    Expecting    a    type    of    %s    in    record    %s' % (step, exp_type, record))
        self.assertTrue((record.agg_type == exp_type), msg)
        for statistic in self.statisticList:
            exp_stat = exp_data[statistic]
            msg = ('Step    %s,    Rule    1:    Expecting    a    %s    of    %s    in    record    %s' % (step, statistic, exp_stat, record))
            self.assertTrue((record[statistic] == exp_stat), msg)
    rows = current.gis.get_parents(location_id)
    location_list = [i.id for i in rows]
    self.assertTrue((len(location_list) == len(expected.rule2.data)))
    query = (((atable.parameter_id == indicator_id) & atable.location_id.belongs(location_list)) & (atable.deleted == False))
    rows = db(query).select(*fields)
    aggr_data = {}
    for row in rows:
        if (row.date in aggr_data):
            aggr_data[row.date][row.location_id] = row
        else:
            aggr_data[row.date] = {row.location_id: row}
    last_exp_data = {}
    for dt in rrule(YEARLY, dtstart=first_period, until=last_period):
        dt = dt.date()
        for location in location_list:
            msg = ('Step    %s,    Rule    2:    Failed    to    find    an    aggregate    record    starting    with    date    %s' % (step, dt))
            self.assertTrue((dt in aggr_data), msg)
            msg = ('Step    %s,    Rule    2:    Failed    to    find    an    aggregate    record    starting    with    date    %s    for    location    %s' % (step, dt, self.location_code[location]))
            self.assertTrue((location in aggr_data[dt]), msg)
            record = aggr_data[dt][location]
            msg = ('Step    %s,    Rule    2:    Expecting    a    type    of    2    in    record    %s' % (step, record))
            self.assertTrue((record.agg_type == 2), msg)
            if (dt in expected.rule2.data[location]):
                exp_data = expected.rule2.data[location][dt]
                last_exp_data[location] = exp_data
            else:
                exp_data = last_exp_data[location]
            for statistic in self.statisticList:
                exp_stat = exp_data[statistic]
                msg = ('Step    %s,    Rule    2:    Expecting    a    %s    of    %s    for    location    %s    in    record    %s' % (step, statistic, exp_stat, self.location_code[location], record))
                self.assertTrue((record[statistic] == exp_stat), msg)
    location_list.append(location_id)
    self.assertTrue((len(location_list) == len(expected.rule3.data)))
    query = (((atable.parameter_id == self.resilience_id) & atable.location_id.belongs(location_list)) & (atable.deleted == False))
    rows = db(query).select(*fields)
    aggr_data = {}
    for row in rows:
        if (row.date in aggr_data):
            aggr_data[row.date][row.location_id] = row
        else:
            aggr_data[row.date] = {row.location_id: row}
    for location in location_list:
        last_exp_data = None
        for dt in rrule(YEARLY, dtstart=first_period, until=last_period):
            dt = dt.date()
            msg = ('Step    %s,    Rule    3:    Failed    to    find    a    resilience    record    starting    with    date    %s' % (step, dt))
            self.assertTrue((dt in aggr_data), msg)
            msg = ('Step    %s,    Rule    3:    Failed    to    find    a    resilience    record    starting    with    date    %s    for    location    %s' % (step, dt, self.location_code[location]))
            self.assertTrue((location in aggr_data[dt]), msg)
            record = aggr_data[dt][location]
            msg = ('Step    %s,    Rule    3:    Expecting    a    type    of    4    in    record    %s' % (step, record))
            self.assertTrue((record.agg_type == 4), msg)
            if (dt in expected.rule3.data[location]):
                exp_data = expected.rule3.data[location][dt]
                last_exp_data = exp_data
            else:
                exp_data = last_exp_data
            for statistic in self.statisticList:
                exp_stat = exp_data[statistic]
                msg = ('Step    %s,    Rule    3:    Expecting    a    %s    of    %s        for    location    %s    in    record    %s' % (step, statistic, exp_stat, self.location_code[location], record))
                self.assertTrue(((record[statistic] - exp_stat) < 1e-07), msg)
