def test_get_one_citizen(self): import_obj = Import() Import.save(import_obj) gen_citizen = generate_one_citizen() db_citizen = Citizen(import_id=import_obj, citizen_id=gen_citizen.citizen_id, town=gen_citizen.town, street=gen_citizen.street, appartement=gen_citizen.appartement, name=gen_citizen.name, birth_date=datetime.datetime.strptime( gen_citizen.birth_date, "%d.%m.%Y"), gender=gen_citizen.gender, building=gen_citizen.building) Citizen.save(db_citizen) response = self.client.get(self.url.format(import_obj.import_id)) self.assertEqual(response.status_code, 200) response_citizens = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_citizens), list) self.assertEqual(len(response_citizens), 1) citizen = response_citizens[0] self.assertEqual(citizen['citizen_id'], db_citizen.citizen_id) self.assertEqual(citizen['town'], db_citizen.town) self.assertEqual(citizen['name'], db_citizen.name) self.assertEqual(citizen['street'], db_citizen.street) self.assertEqual(citizen['building'], db_citizen.building) self.assertEqual(citizen['appartement'], db_citizen.appartement) self.assertEqual(citizen['gender'], db_citizen.gender) self.assertEqual(citizen['birth_date'], gen_citizen.birth_date) self.assertEqual(citizen['relatives'], [])
def test_change_info_citizen(self): import_obj = Import() Import.save(import_obj) citizen = generate_one_citizen() db_citizen = Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) Citizen.save(db_citizen) data = {"name": "Новое имя"} response = self.client.patch(self.url.format(import_obj.import_id, db_citizen.citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['citizen_id'], db_citizen.citizen_id) self.assertEqual(response_citizen['town'], db_citizen.town) self.assertEqual(response_citizen['birth_date'], citizen.birth_date) self.assertEqual(response_citizen['name'], data['name']) data = { "name": "Другое новое имя", "town": "Новый город", "street": "Ну совсем другая", "building": "New building", "appartement": 100000, "birth_date": "12.01.2019", "gender": "male", } response = self.client.patch(self.url.format(import_obj.import_id, db_citizen.citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['citizen_id'], db_citizen.citizen_id) self.assertEqual(response_citizen['town'], data['town']) self.assertEqual(response_citizen['birth_date'], data['birth_date']) self.assertEqual(response_citizen['name'], data['name']) self.assertEqual(response_citizen['gender'], data['gender']) self.assertEqual(response_citizen['appartement'], data['appartement']) self.assertEqual(response_citizen['building'], data['building']) self.assertEqual(response_citizen['street'], data['street'])
def test_change_relatives_citizen_delete(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(3, provide_relatives=False) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) db_citizens[0].relatives.set(db_citizens[1:]) data = {"relatives": []} response = self.client.patch(self.url.format( import_obj.import_id, db_citizens[0].citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['citizen_id'], db_citizens[0].citizen_id) self.assertEqual(response_citizen['relatives'], data["relatives"]) citizen2 = Citizen.objects.get(id=db_citizens[1].id) citizen3 = Citizen.objects.get(id=db_citizens[2].id) self.assertEqual(citizen2.relatives.count(), 0) self.assertEqual(citizen3.relatives.count(), 0)
def create(self, validated_data): citizens_data = validated_data.pop('citizens') data_import = Import.objects.create(**validated_data) citizens = [] relations = OrderedDict() for citizen_data in citizens_data: citizen_id = citizen_data['citizen_id'] relations[citizen_id] = set(citizen_data.pop('relatives')) citizens.append( Citizen(data_import_id=data_import.pk, **citizen_data)) citizen_ids = Citizen.objects.bulk_create(citizens) # TODO: Think how to validate on `is_valid()` self.validate_relations(relations) citizen_relations = [] for relation, citizen_pk in zip(relations.values(), citizen_ids): for citizen_id in relation: citizen_relations.append( CitizenRelations(from_citizen=citizen_pk, to_citizen_id=citizen_id)) CitizenRelations.objects.bulk_create(citizen_relations) return data_import
def generate_citizens_in_db(import_obj, count=1, to_return='gen'): gen_citizens = generate_citizens(count) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime(citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) relatives = [ Citizen.relatives.through( from_citizen_id=db_citizens[citizen.citizen_id - 1].id, to_citizen_id=db_citizens[cit_id - 1].id) for citizen in gen_citizens for cit_id in citizen.relatives ] Citizen.relatives.through.objects.bulk_create(relatives) if to_return == 'gen': return gen_citizens elif to_return == 'db': return db_citizens return gen_citizens, db_citizens
def test_get_three_citizens(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(3, provide_relatives=False) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) db_citizens[0].relatives.set(db_citizens[1:]) response = self.client.get(self.url.format(import_obj.import_id)) self.assertEqual(response.status_code, 200) response_citizens = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_citizens), list) self.assertEqual(len(response_citizens), 3) for json_citizen in response_citizens: self.assertEqual( json_citizen['citizen_id'], db_citizens[json_citizen['citizen_id'] - 1].citizen_id) self.assertEqual(json_citizen['town'], db_citizens[json_citizen['citizen_id'] - 1].town) self.assertEqual(json_citizen['name'], db_citizens[json_citizen['citizen_id'] - 1].name) self.assertEqual( json_citizen['street'], db_citizens[json_citizen['citizen_id'] - 1].street) self.assertEqual( json_citizen['building'], db_citizens[json_citizen['citizen_id'] - 1].building) self.assertEqual( json_citizen['appartement'], db_citizens[json_citizen['citizen_id'] - 1].appartement) self.assertEqual( json_citizen['gender'], db_citizens[json_citizen['citizen_id'] - 1].gender) self.assertEqual( json_citizen['birth_date'], gen_citizens[json_citizen['citizen_id'] - 1].birth_date) self.assertEqual( len(json_citizen['relatives']), db_citizens[json_citizen['citizen_id'] - 1].relatives.count()) self.assertEqual( set(json_citizen['relatives']), { rel.citizen_id for rel in db_citizens[json_citizen['citizen_id'] - 1].relatives.all() })
def test_max_citizen_batch(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(10000, provide_relatives=False) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) ages = {} for citizen in db_citizens: today = datetime.datetime.utcnow().date() if citizen.town in ages.keys(): ages[citizen.town].append( today.year - citizen.birth_date.year - ((today.month, today.day) < (citizen.birth_date.month, citizen.birth_date.day))) else: ages.update({ citizen.town: [ today.year - citizen.birth_date.year - ((today.month, today.day) < (citizen.birth_date.month, citizen.birth_date.day)) ] }) s = datetime.datetime.now() response = self.client.get(self.url.format(import_obj.import_id)) e = datetime.datetime.now() self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_data), list) self.assertEqual(len(response_data), len(ages.keys())) for town_info in response_data: self.assertEqual( town_info['p50'], round(numpy.percentile(ages[town_info['town']], 50), 2)) self.assertEqual( town_info['p75'], round(numpy.percentile(ages[town_info['town']], 75), 2)) self.assertEqual( town_info['p99'], round(numpy.percentile(ages[town_info['town']], 99), 2)) print("Percentile - {}".format((e - s).total_seconds())) self.assertLess((e - s).total_seconds(), 5.0)
def test_small_citizen_batch(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(3, provide_relatives=False) gen_citizens[0].birth_date = '26.12.1986' gen_citizens[1].birth_date = '17.04.1997' gen_citizens[2].birth_date = '23.11.1986' db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) db_citizens[0].relatives.set(db_citizens[1:]) response = self.client.get(self.url.format(import_obj.import_id)) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_data), dict) self.assertEqual(len(response_data.keys()), 12) for key, value in response_data.items(): if key in ['1', '2', '3', '5', '6', '7', '8', '9', '10']: self.assertEqual(value, []) continue if key in ['4', '11']: self.assertEqual(value, [{"citizen_id": 1, "presents": 1}]) continue self.assertEqual(len(value), 2) if value[0]['citizen_id'] == 2: self.assertEqual(value[0], {"citizen_id": 2, "presents": 1}) self.assertEqual(value[1], {"citizen_id": 3, "presents": 1}) else: self.assertEqual(value[1], {"citizen_id": 2, "presents": 1}) self.assertEqual(value[0], {"citizen_id": 3, "presents": 1})
def test_small_citizen_batch(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(100, provide_relatives=False) for citizen in gen_citizens: citizen.town = random.choice(['Москва', 'Ташкент']) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) ages = {'Москва': [], 'Ташкент': []} for citizen in db_citizens: today = datetime.datetime.utcnow().date() ages[citizen.town].append(today.year - citizen.birth_date.year - ( (today.month, today.day) < (citizen.birth_date.month, citizen.birth_date.day))) response = self.client.get(self.url.format(import_obj.import_id)) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_data), list) self.assertEqual(len(response_data), 2) for town_info in response_data: self.assertEqual( town_info['p50'], round(numpy.percentile(ages[town_info['town']], 50), 2)) self.assertEqual( town_info['p75'], round(numpy.percentile(ages[town_info['town']], 75), 2)) self.assertEqual( town_info['p99'], round(numpy.percentile(ages[town_info['town']], 99), 2))
def test_change_relatives_citizen_add(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(3, provide_relatives=False) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) db_citizens[0].relatives.add(db_citizens[1]) data = {"name": "Новое имя", "town": "Переехала", "relatives": [1]} response = self.client.patch(self.url.format( import_obj.import_id, db_citizens[2].citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['name'], data['name']) self.assertEqual(response_citizen['town'], data['town']) self.assertEqual(response_citizen['street'], db_citizens[2].street) self.assertEqual(response_citizen['relatives'], [1]) fcitizen = Citizen.objects.get(id=db_citizens[0].id) fcitizen_relatives = [ rel.citizen_id for rel in fcitizen.relatives.all() ] self.assertEqual(set(fcitizen_relatives), {2, 3}) scitizen = Citizen.objects.get(id=db_citizens[1].id) scitizen_relatives = [ rel.citizen_id for rel in scitizen.relatives.all() ] self.assertEqual(scitizen_relatives, [1])
def test_with_precalculated_data(self): answer = { "Ташкент": { "p50": 33, "p75": 61, "p99": 77.9 }, "Москва": { "p50": 23, "p75": 25.5, "p99": 61.2 } } import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(22, provide_relatives=False) moscow, tashkent = "Москва", "Ташкент" gen_citizens[0].birth_date = "01.01.2009" gen_citizens[1].birth_date = "01.01.1956" gen_citizens[2].birth_date = "01.01.1960" gen_citizens[3].birth_date = "01.01.1998" gen_citizens[4].birth_date = "01.01.1990" gen_citizens[5].birth_date = "01.01.1942" gen_citizens[6].birth_date = "01.01.1975" gen_citizens[7].birth_date = "01.01.1986" gen_citizens[8].birth_date = "01.01.2001" gen_citizens[9].birth_date = "01.01.2004" gen_citizens[10].birth_date = "01.01.1941" gen_citizens[11].birth_date = "01.01.2001" gen_citizens[12].birth_date = "01.01.2000" gen_citizens[13].birth_date = "01.01.1999" gen_citizens[14].birth_date = "01.01.1998" gen_citizens[15].birth_date = "01.01.1997" gen_citizens[16].birth_date = "01.01.1996" gen_citizens[17].birth_date = "01.01.1995" gen_citizens[18].birth_date = "01.01.1994" gen_citizens[19].birth_date = "01.01.1993" gen_citizens[20].birth_date = "01.01.1992" gen_citizens[21].birth_date = "01.01.1954" for i in range(11): gen_citizens[i].town = tashkent gen_citizens[i + 11].town = moscow db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) response = self.client.get(self.url.format(import_obj.import_id)) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(type(response_data), list) self.assertEqual(len(response_data), 2) for town_info in response_data: self.assertEqual(town_info['p50'], answer[town_info['town']]['p50']) self.assertEqual(town_info['p75'], answer[town_info['town']]['p75']) self.assertEqual(town_info['p99'], answer[town_info['town']]['p99'])
def test_change_relatives_citizen_mix(self): import_obj = Import() Import.save(import_obj) gen_citizens = generate_citizens(6, provide_relatives=False) db_citizens = [ Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date=datetime.datetime.strptime( citizen.birth_date, "%d.%m.%Y"), gender=citizen.gender, building=citizen.building) for citizen in gen_citizens ] Citizen.objects.bulk_create(db_citizens) db_citizens[0].relatives.set([db_citizens[1], db_citizens[3]]) db_citizens[1].relatives.add(db_citizens[3]) db_citizens[4].relatives.set([db_citizens[5], db_citizens[2]]) db_citizens[5].relatives.add(db_citizens[2]) data = {"relatives": [1, 5]} response = self.client.patch(self.url.format( import_obj.import_id, db_citizens[2].citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['citizen_id'], db_citizens[2].citizen_id) self.assertEqual(set(response_citizen['relatives']), set(data["relatives"])) data = {"relatives": [2, 6]} response = self.client.patch(self.url.format( import_obj.import_id, db_citizens[3].citizen_id), json.dumps(data), content_type='application/json') data = {"relatives": [2, 6]} response = self.client.patch(self.url.format( import_obj.import_id, db_citizens[3].citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 200) response_citizen = json.loads(response.content.decode('utf8'))['data'] self.assertEqual(response_citizen['citizen_id'], db_citizens[3].citizen_id) self.assertEqual(set(response_citizen['relatives']), set(data["relatives"])) citizen1 = Citizen.objects.get(id=db_citizens[0].id) citizen_relatives1 = [ rel.citizen_id for rel in citizen1.relatives.all() ] self.assertEqual(set(citizen_relatives1), {2, 3}) citizen2 = Citizen.objects.get(id=db_citizens[1].id) citizen_relatives2 = [ rel.citizen_id for rel in citizen2.relatives.all() ] self.assertEqual(set(citizen_relatives2), {1, 4}) citizen5 = Citizen.objects.get(id=db_citizens[4].id) citizen_relatives5 = [ rel.citizen_id for rel in citizen5.relatives.all() ] self.assertEqual(set(citizen_relatives5), {3, 6}) citizen6 = Citizen.objects.get(id=db_citizens[5].id) citizen_relatives6 = [ rel.citizen_id for rel in citizen6.relatives.all() ] self.assertEqual(set(citizen_relatives6), {4, 5})
def test_bad_data(self): data = {"name": "Новое Имя", "birth_date": "01.01.2019"} data.update({"citizen_id": 1}) response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": 1, "birth_date": "01.01.2019"} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": "New name", "appartement": "1"} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": "New name", "appartement": -100} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": "Новое имя", "birth_date": "01-01-2019"} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": "Новое имя", "town": None} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"name": "Новое имя", "redundant": "redundant"} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {} response = self.client.patch(self.url.format(0, 0), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) import_obj = Import() Import.save(import_obj) citizen = generate_one_citizen() db_citizen = Citizen(import_id=import_obj, citizen_id=citizen.citizen_id, town=citizen.town, street=citizen.street, appartement=citizen.appartement, name=citizen.name, birth_date="1955-11-29", gender=citizen.gender, building=citizen.building) Citizen.save(db_citizen) data = {"name": "Новое имя", "relatives": [1000000]} response = self.client.patch(self.url.format(import_obj.import_id, db_citizen.citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 404) data = {"birth_date": "12.12.2019"} response = self.client.patch(self.url.format(import_obj.import_id, db_citizen.citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400) data = {"gender": "gender"} response = self.client.patch(self.url.format(import_obj.import_id, db_citizen.citizen_id), json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 400)