def test_filter_regions(self): """ [recommendation.filter.Region] Test a region filter on recommendation """ rfilter = SimpleRegionFilter() recommendation = [random.random() for _ in range(len(ITEMS))] app_rec = [ Item.get_item_by_id(aid + 1).external_id for aid, _ in sorted( enumerate(recommendation), key=lambda x: x[1], reverse=True) ] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [ Item.get_item_by_id(aid + 1).external_id for aid, _ in sorted( enumerate(result), key=lambda x: x[1], reverse=True) ] n = len(u["last_apps_region"]) if n == 0: assert new_rec == app_rec, \ "Recommendation is not the same when not apps to filter(%s != %s)" % (new_rec, app_rec) else: for item in u["last_apps_region"]: assert item in new_rec[0-n:], \ "Item %s for user %s is not in the last in recommendation %s. Items filtered %s." % \ (item, user, new_rec, list(u["last_apps_region"]))
def get(self, request, user_external_id): """ Get the users owned items. It receives an extra set of GET parameters. The offset and the items. The ´´offset´´ represents the amount of items to pass before start sending results. The ´´items´´ represents the amount of items to show. :param request: The HTTP request. :param user_external_id: The user external id that are making the request. :return: A list of app external ids of the user owned (items that are in database with reference to this user and the dropped date set to null). """ offset = int(request.GET.get("offset", 0)) # Offset of items number_of_items = int(request.GET.get("items", 0)) # Number of items to present limit = (offset+number_of_items) or None user = User.get_user_by_external_id(user_external_id) try: items = [ { "external_id": Item.get_item_external_id_by_id(item_id), "is_dropped": is_dropped } for item_id, is_dropped in User.get_user_items(user.pk).items()[offset:limit] ] except KeyError: return self.format_response(self.NOT_FOUND_ERROR_MESSAGE, status=NOT_FOUND_ERROR) data = {"user": user_external_id, "items": items} return self.format_response(data)
def get(self, request, user_external_id): """ Get the users owned items. It receives an extra set of GET parameters. The offset and the items. The ´´offset´´ represents the amount of items to pass before start sending results. The ´´items´´ represents the amount of items to show. :param request: The HTTP request. :param user_external_id: The user external id that are making the request. :return: A list of app external ids of the user owned (items that are in database with reference to this user and the dropped date set to null). """ offset = int(request.GET.get("offset", 0)) # Offset of items number_of_items = int(request.GET.get("items", 0)) # Number of items to present limit = (offset + number_of_items) or None user = User.get_user_by_external_id(user_external_id) try: items = [{ "external_id": Item.get_item_external_id_by_id(item_id), "is_dropped": is_dropped } for item_id, is_dropped in User.get_user_items(user.pk).items() [offset:limit]] except KeyError: return self.format_response(self.NOT_FOUND_ERROR_MESSAGE, status=NOT_FOUND_ERROR) data = {"user": user_external_id, "items": items} return self.format_response(data)
def test_get_item_by_external_id(self): """ [recommendation.models.User] Test queries by external id made by getting user and check integrity of that user """ with self.assertNumQueries(0): for u in USERS: user = User.get_user_by_external_id(u["external_id"]) assert isinstance(user, User), "Cached user is not instance of User."
def test_size_of_logs_in_cache(self): """ [recommendation.cache.SimpleLogger] Test size of cache is 10 for all users in system """ for user in USERS: user = User.get_user_by_external_id(user["external_id"]) assert len(LogEntry.get_logs_for(user.pk)) == 10, \ "logs size are bigger than predicted (%s != 10)" % len(LogEntry.get_logs_for(user.pk))
def test_user_items(self): """ [recommendation.models.User] Test user items """ for u in USERS: user = User.get_user_by_external_id(u["external_id"]) for i in u["items"]: assert Item.get_item_by_external_id(i).pk in user.all_items, \ "Item %s is not in user %s" % (i, user.external_id)
def test_recommendation_size_after_filter(self): """ [recommendation.filter.Region] Test the size of the recommendation after the filter """ rfilter = SimpleRegionFilter() recommendation = [random.random() for _ in range(len(ITEMS))] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [aid+1 for aid, _ in sorted(enumerate(result), key=lambda x: x[1], reverse=True)] assert len(new_rec) == len(ITEMS), "Recommendation size changed (%d != %s)" % (len(new_rec), len(ITEMS))
def test_click_logging(self): """ [recommendation.decorator.SimpleLogger] Test if a clicked item is logged """ logger = LogEvent(LogEvent.CLICK) user = User.get_user_by_external_id("joaonrb") logger(lambda uid, iid: None)(user, Item.get_item_by_external_id("10004")) time.sleep(1.) logs = list(LogEntry.objects.filter(user=user, type=logger.CLICK)) assert len(logs) == 1, "Number of register is not correct %s" % logs assert "10004" == logs[0].item.external_id, \ "The item in log is incorrect(1004 != %s)" % logs[0].item.external_id
def test_acquire_logging(self): """ [recommendation.decorator.SimpleLogger] Test if a acquired item is logged """ logger = LogEvent(LogEvent.ACQUIRE) user = User.get_user_by_external_id("joaonrb") logger(lambda uid, iid: None)(user, Item.get_item_by_external_id("10004")) time.sleep(1.) logs = list(LogEntry.objects.filter(user=user, type=logger.ACQUIRE)) assert len(logs) == 1, "Number of register is not correct %s" % logs assert "10004" == logs[0].item.external_id, \ "The item in log is incorrect(1004 != %s)" % logs[0].item.external_id
def test_reranker_diversity(self): """ [recommendation.diversity.ReRanker] Test a diversity re-ranker on recommendation """ diversity = SimpleDiversityReRanker() recommendation = [Item.get_item_by_external_id(i).pk for i in ("10001", "10002", "10003", "10004", "98766")] shuffle(recommendation) for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = diversity(user=user, recommendation=recommendation[:], size=5) new_rec = [aid+1 for aid, _ in sorted(enumerate(result), key=lambda x: x[1], reverse=True)] assert len(result) == len(ITEMS), "Recommendation size changed (%d != %s)" % (len(new_rec), len(ITEMS))
def test_owned_items(self): """ [recommendation.models.User] Test owned items """ for u in USERS: user = User.get_user_by_external_id(u["external_id"]) for i in u["items"]: ivent = Inventory.objects.get(item=user.all_items[Item.get_item_by_external_id(i).pk], user=user) ivent.is_dropped = True ivent.save() assert Item.get_item_by_external_id(i).pk not in user.owned_items, \ "Item %s is in user %s owned items" % (i, user.external_id) ivent = Inventory.objects.get(item=user.all_items[Item.get_item_by_external_id(i).pk], user=user) ivent.is_dropped = False ivent.save()
def test_recommendation_update_user(self): """ [recommendation.api.GetUserItems] Test update user items """ response = self.client.put( "/api/v2/user-items/00504e6196ab5fa37ae7450dad99d031a80c50ef4b762c15151a2e4e92c64e0b/", '{"user_items": ["504343", "413346"]}', content_type="application/json" ) sleep(0.8) user = User.get_user_by_external_id("00504e6196ab5fa37ae7450dad99d031a80c50ef4b762c15151a2e4e92c64e0b") assert response.status_code == 200, "Request failed. Status code %d." % response.status_code assert len(user.owned_items) == 2, "Owned items should be 3(%d)" % len(user.owned_items) assert Item.get_item_by_external_id("504343").pk in user.owned_items, "New item not in owned items" assert Item.get_item_by_external_id("413346").pk in user.owned_items, "New item not in owned items"
def test_recommendation_remove_new_item(self): """ [recommendation.api.GetUserItems] Test remove old item """ response = self.client.delete( "/api/v2/user-items/006a508fe63e87619db5c3db21da2c536f24e296c29d885e4b48d0b5aa561173/", "item_to_remove=413346", content_type="application/x-www-form-urlencoded; charset=UTF-8" ) sleep(0.8) assert response.status_code == 200, "Request failed. Status code %d. Message: %s" % \ (response.status_code, json.loads(response.content).get("error", "")) assert len(User.get_user_by_external_id( "006a508fe63e87619db5c3db21da2c536f24e296c29d885e4b48d0b5aa561173").owned_items) == 0, \ "Owned items should be 0"
def get_external_id_recommendations(self, user, n=10): """ Returns the recommendations with a list of external_is's :param user: Same parameters that get_app_significance :param n: :return: Item external id list """ try: user = User.get_user_by_external_id(user) except IndexError: logging.info("User %s not exist. Is going to be created") user = User.objects.create(external_id=user) result = self.get_recommendation(user=user, n=n) return [Item.get_item_external_id_by_id(r) for r in result]
def test_filter_owned(self): """ [recommendation.filter.OwnedIems] Test a filter owned items on recommendation """ rfilter = FilterOwned() recommendation = [random.random() for _ in range(len(ITEMS))] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [aid+1 for aid, _ in sorted(enumerate(result), key=lambda x: x[1], reverse=True)] n = len(user.owned_items) for item in user.owned_items: assert item in new_rec[0-n:], "Item %d is not in the last in recommendation %s. User owned items %s" % \ (item, new_rec, list(user.owned_items.keys()))
def test_recommendation_acquire_new_item(self): """ [recommendation.api.GetUserItems] Test acquire new item """ user = User.get_user_by_external_id("00504e6196ab5fa37ae7450dad99d031a80c50ef4b762c15151a2e4e92c64e0b") items = user.owned_items response = self.client.post( "/api/v2/user-items/00504e6196ab5fa37ae7450dad99d031a80c50ef4b762c15151a2e4e92c64e0b/", {"item_to_acquire": "504343"} ) sleep(0.8) assert response.status_code == 200, "Request failed. Status code %d." % response.status_code assert len(user.owned_items) == len(items)+1, "Owned items should be %d(%d)" % (len(items)+1, len(user.owned_items)) assert Item.get_item_by_external_id("504343").pk in user.owned_items.keys(), "New item not in owned items"
def test_recommendation_logging(self): """ [recommendation.decorator.SimpleLogger] Test if a recommendation is logged """ logger = LogEvent(LogEvent.RECOMMEND) user = User.get_user_by_external_id("joaonrb") recommendation = [Item.get_item_by_external_id(i).pk for i in ("10001", "10002", "10003", "10004", "98766")] recommendation = logger(lambda user: recommendation)(user=user) time.sleep(1.) logs = list(LogEntry.objects.filter(user=user, type=logger.RECOMMEND).order_by("value")) assert len(logs) == 5, "Number of register is not correct %s" % logs logs_iter = iter(logs) for i, item in enumerate(recommendation, start=1): log = logs_iter.next() assert item == log.item.pk, "The item in position %d is not the same that in recommendation " \ "(%s != %s)" % (i, item, log.item.external_id) assert i == log.value, "The item in position %d do not have the right value. (%d)" % (i, log.value)
def test_recommendation_size_after_filter(self): """ [recommendation.filter.Region] Test the size of the recommendation after the filter """ rfilter = SimpleRegionFilter() recommendation = [random.random() for _ in range(len(ITEMS))] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [ aid + 1 for aid, _ in sorted( enumerate(result), key=lambda x: x[1], reverse=True) ] assert len(new_rec) == len( ITEMS), "Recommendation size changed (%d != %s)" % ( len(new_rec), len(ITEMS))
def delete(self, request, user_external_id): """ removes an old item in the user installed apps. It should have a special POST parameter (besides the csrf token or other token needed to the connection) that is item_to_acquire. The ´´item_to_remove´´ is the item external id that is supposed to be removed in the user inventory. :param request: The HTTP request. :param user_external_id: The user external id that are making the request. :return: A success response if the input was successful =p """ try: item_id = request.DATA["item_to_remove"] except KeyError: return self.format_response(PARAMETERS_IN_MISS, status=FORMAT_ERROR) self.remove_item(User.get_user_by_external_id(user_external_id), Item.get_item_by_external_id(item_id)) return self.format_response(SUCCESS_MESSAGE)
def test_filter_owned(self): """ [recommendation.filter.OwnedIems] Test a filter owned items on recommendation """ rfilter = FilterOwned() recommendation = [random.random() for _ in range(len(ITEMS))] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [ aid + 1 for aid, _ in sorted( enumerate(result), key=lambda x: x[1], reverse=True) ] n = len(user.owned_items) for item in user.owned_items: assert item in new_rec[0-n:], "Item %d is not in the last in recommendation %s. User owned items %s" % \ (item, new_rec, list(user.owned_items.keys()))
def post(self, request, user_external_id): """ Inserts a new item in the user owned items. It should have a special POST parameter (besides the csrf token or other token needed to the connection - to development and presentation purposes the csrf was disabled) that is item_to_acquire. The ´´item_to_acquire´´ is the item external id that is supposed to be in the user inventory. :param request: The HTTP request. :param user_external_id: The user external id that are making the request. :return: A success response if the input was successful =p """ try: item_id = request.POST["item_to_acquire"] except KeyError: return self.format_response(PARAMETERS_IN_MISS, status=FORMAT_ERROR) self.insert_acquisition(User.get_user_by_external_id(user_external_id), Item.get_item_by_external_id(item_id)) return self.format_response(SUCCESS_MESSAGE)
def test_recommendation_logging(self): """ [recommendation.decorator.SimpleLogger] Test if a recommendation is logged """ logger = LogEvent(LogEvent.RECOMMEND) user = User.get_user_by_external_id("joaonrb") recommendation = [ Item.get_item_by_external_id(i).pk for i in ("10001", "10002", "10003", "10004", "98766") ] recommendation = logger(lambda user: recommendation)(user=user) time.sleep(1.) logs = list( LogEntry.objects.filter(user=user, type=logger.RECOMMEND).order_by("value")) assert len(logs) == 5, "Number of register is not correct %s" % logs logs_iter = iter(logs) for i, item in enumerate(recommendation, start=1): log = logs_iter.next() assert item == log.item.pk, "The item in position %d is not the same that in recommendation " \ "(%s != %s)" % (i, item, log.item.external_id) assert i == log.value, "The item in position %d do not have the right value. (%d)" % ( i, log.value)
def test_filter_regions(self): """ [recommendation.filter.Region] Test a region filter on recommendation """ rfilter = SimpleRegionFilter() recommendation = [random.random() for _ in range(len(ITEMS))] app_rec = [Item.get_item_by_id(aid+1).external_id for aid, _ in sorted(enumerate(recommendation), key=lambda x: x[1], reverse=True)] for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = rfilter(user, np.array(recommendation[:])) new_rec = [Item.get_item_by_id(aid+1).external_id for aid, _ in sorted(enumerate(result), key=lambda x: x[1], reverse=True)] n = len(u["last_apps_region"]) if n == 0: assert new_rec == app_rec, \ "Recommendation is not the same when not apps to filter(%s != %s)" % (new_rec, app_rec) else: for item in u["last_apps_region"]: assert item in new_rec[0-n:], \ "Item %s for user %s is not in the last in recommendation %s. Items filtered %s." % \ (item, user, new_rec, list(u["last_apps_region"]))
def put(self, request, user_external_id): """ Replaces all the user items with the list of given items. It should have a PUT body parameter items_to_acquire (besides the csrf token or other token needed to the connection - to development and presentation purposes the csrf was disabled) that is. The ´´items_to_acquire´´ is the list of items external ids that will become a new user inventory. :param request: The HTTP request. :param user_external_id: The user external id that are making the request. :return: A success response if the input was successful =p """ try: items_ids = request.DATA["user_items"] except KeyError: return self.format_response(PARAMETERS_IN_MISS, status=FORMAT_ERROR) try: user = User.get_user_by_external_id(user_external_id) except User.DoesNotExist: user = User.objects.create(external_id=user_external_id) items = [Item.get_item_by_external_id(iid) for iid in items_ids] self.update_user_items(user, items) return self.format_response(SUCCESS_MESSAGE)
def test_check_std_recommendation(self): """ [recommendation.core.TensorCoFiController] Test get default recommendation """ rec_controller = get_controller() for u in USERS: recommendation = rec_controller.get_recommendation(user=User.get_user_by_external_id(u["external_id"]), n=5) assert len(recommendation) == 5, "Size of recommendation is not right" #@ut.skipIf("default" not in RECOMMENDATION_SETTINGS, "Default recommendation is not defined") #def test_check_alternative_recommendation(self): # """ # [recommendation.core.TensorCoFiController] Test get alternative recommendation # """ # rec_controller = get_controller() # pop_result = \ # [aid+1 for aid, _ in sorted(enumerate(Popularity.get_model().recommendation), # key=lambda x: x[1], reverse=True)] # for name in ["Gepeto", "Son_Goku", "Peter_Pan", "Tony_Montana", "Lady_Diana"]: # user = User.objects.create(external_id=name) # recommendation = rec_controller.get_recommendation(user=user, n=5) # #assert len(recommendation) == 5, "Size of recommendation is not right" # assert recommendation == pop_result[:len(recommendation)], \ # "Recommendation is not popularity for user %s (%s != %s)" % (user, recommendation, pop_result)
def test_reranker_diversity_no_redundancy(self): """ [recommendation.diversity.ReRanker] Test a diversity re-ranker on recommendation for non redundancy and loss """ diversity = SimpleDiversityReRanker() recommendation = [ Item.get_item_by_external_id(i).pk for i in ("10001", "10002", "10003", "10004", "98766") ] shuffle(recommendation) for u in USERS: user = User.get_user_by_external_id(u["external_id"]) with self.assertNumQueries(0): result = diversity(user=user, recommendation=recommendation[:], size=5) new_rec = [ aid + 1 for aid, _ in sorted( enumerate(result), key=lambda x: x[1], reverse=True) ] assert len(set(result)) == len( ITEMS), "Recommendation size changed (%d != %s)" % ( len(new_rec), len(ITEMS))