def main(): if len(sys.argv) < 4: usage() exit() db = TahrirDatabase(sys.argv[1]) issuer_id = db.add_issuer( "http://coderwall.com", "coderwall", "http://coderwall.com", "*****@*****.**" ) db.add_person(hash(sys.argv[3]), sys.argv[3]) cw = CoderWall(sys.argv[2]) for badge in cw.badges: db.add_badge( badge.name, badge.image_uri, badge.description, "http://coderwall.com", issuer_id) db.add_assertion( badge.name.lower(), sys.argv[3], None ) print "Awarded {0} badges to {1}".format(len(cw.badges), sys.argv[3])
class TestRanking(object): def setUp(self): check_output(['touch', 'testdb.db']) sqlalchemy_uri = "sqlite:///testdb.db" engine = create_engine(sqlalchemy_uri) DBSession.configure(bind=engine) DeclarativeBase.metadata.create_all(engine) self.api = TahrirDatabase(sqlalchemy_uri) self._create_test_data() def tearDown(self): check_output(['rm', 'testdb.db']) def _create_test_data(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) self.badge_id_1 = self.api.add_badge( "TestBadge1", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.badge_id_2 = self.api.add_badge( "TestBadge2", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.badge_id_3 = self.api.add_badge( "TestBadge3", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.email_1 = "*****@*****.**" person_id_1 = self.api.add_person(self.email_1) self.email_2 = "*****@*****.**" person_id_2 = self.api.add_person(self.email_2) self.email_3 = "*****@*****.**" person_id_3 = self.api.add_person(self.email_3) self.email_4 = "*****@*****.**" person_id_4 = self.api.add_person(self.email_4) def test_ranking_simple(self): self.api.add_assertion(self.badge_id_1, self.email_1, None) self.api.add_assertion(self.badge_id_1, self.email_4, None) self.api.add_assertion(self.badge_id_2, self.email_4, None) self.api.add_assertion(self.badge_id_3, self.email_4, None) person1 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") eq_(person1.rank, 2) eq_(person4.rank, 1) def test_ranking_tie(self): self.api.add_assertion(self.badge_id_1, self.email_1, None) self.api.add_assertion(self.badge_id_1, self.email_2, None) self.api.add_assertion(self.badge_id_2, self.email_2, None) self.api.add_assertion(self.badge_id_1, self.email_3, None) self.api.add_assertion(self.badge_id_2, self.email_3, None) self.api.add_assertion(self.badge_id_1, self.email_4, None) self.api.add_assertion(self.badge_id_2, self.email_4, None) self.api.add_assertion(self.badge_id_3, self.email_4, None) person1 = self.api.get_person("*****@*****.**") person2 = self.api.get_person("*****@*****.**") person3 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") eq_(person1.rank, 4) eq_(person2.rank, 2) eq_(person3.rank, 2) eq_(person4.rank, 1) def test_ranking_preexisting(self): """ Test that rank updating works for pre-existant users """ person1 = self.api.get_person("*****@*****.**") new_assertion1 = Assertion( badge_id=self.badge_id_1, person_id=person1.id, ) self.api.session.add(new_assertion1) new_assertion2 = Assertion( badge_id=self.badge_id_2, person_id=person1.id, ) self.api.session.add(new_assertion2) self.api.session.flush() # For persons who existed *before* we added cached ranks, they should # have a null-rank. eq_(person1.rank, None) # But once *anyone* else gets a badge, old ranks should be updated too. self.api.add_assertion(self.badge_id_1, self.email_2, None) eq_(person1.rank, 1) person2 = self.api.get_person("*****@*****.**") eq_(person2.rank, 2) # but people with no badges should still be null ranked. person3 = self.api.get_person("*****@*****.**") eq_(person3.rank, None) def test_ranking_with_time_limits(self): self.api.add_assertion(self.badge_id_1, self.email_1, yesterday) self.api.add_assertion(self.badge_id_1, self.email_4, yesterday) self.api.add_assertion(self.badge_id_2, self.email_4, one_week_ago) self.api.add_assertion(self.badge_id_3, self.email_4, one_month_ago) person1 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") epsilon = datetime.timedelta(hours=1) results = self.api._make_leaderboard(yesterday - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 1) results = self.api._make_leaderboard(one_week_ago - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 2) results = self.api._make_leaderboard(one_month_ago - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 3)
class FedoraBadgesConsumer(FedmsgConsumer): """ The Base class for creating fedmsg consumers that issue open badges Provides a base that does all of the heavy lifting related to issuing badges. All the subclass needs to do is have a topic, a name, and implement consume(self, msg) :type hub: Moksha Hub :param hub: the moksha hub we are getting our messages from :type name: str :param name: name of this consumer, used to get details from the config file """ def __init__(self, hub, name): self.name = name self.badges = {} self.hub = hub self.DBSession = None ENABLED = "fedmsg.consumers.badges.{0}.enabled".format(self.name) if not asbool(hub.config.get(ENABLED, False)): log.info("fedmsg.consumers.badges.{0} disabled".format(self.name)) return global_settings = hub.config.get("badges_global") database_uri = global_settings.get("database_uri", "") if database_uri == "": raise Exception("Badges consumer requires a database uri") return self.tahrir = TahrirDatabase(database_uri) self.DBSession = self.tahrir.session_maker issuer = global_settings.get("badge_issuer") self.issuer_id = self.tahrir.add_issuer( issuer.get("issuer_origin"), issuer.get("issuer_name"), issuer.get("issuer_org"), issuer.get("issuer_contact"), ) badges_settings = hub.config.get("{0}_badges".format(self.name)) for badge in badges_settings: self.tahrir.add_badge( badge.get("badge_name"), badge.get("badge_image"), badge.get("badge_desc"), badge.get("badge_criteria"), self.issuer_id, ) return super(FedoraBadgesConsumer, self).__init__(hub) def award_badge(self, email, badge_id, issued_on=None): """ A high level way to issue a badge to a Person It adds the person if they don't exist, and creates an assertion for them :type email: str :param email: This person's email addr :type badge_id: str :param badge_id: the id of the badge being awarded :type issued_on: DateTime :param issued_on: A datetime object with the time this badge was issued """ self.tahrir.add_person(email) self.tahrir.add_assertion(badge_id, email, issued_on) def consume(self, msg): """ Consume a single message, we pass here because every subclass is going to want to parse this slightly differently :type msg: dict :param msg: The message to be parsed """ pass
class TestDBInit(object): def setUp(self): check_output(['touch', 'testdb.db']) sqlalchemy_uri = "sqlite:///testdb.db" engine = create_engine(sqlalchemy_uri) DBSession.configure(bind=engine) DeclarativeBase.metadata.create_all(engine) self.callback_calls = [] self.api = TahrirDatabase( sqlalchemy_uri, notification_callback=self.callback) def callback(self, *args, **kwargs): self.callback_calls.append((args, kwargs)) def test_add_badges(self): self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337 ) assert self.api.badge_exists("testbadge") is True def test_add_team(self): self.api.create_team("TestTeam") assert self.api.team_exists("testteam") is True def test_add_series(self): team_id = self.api.create_team("TestTeam") self.api.create_series("TestSeries", "A test series", team_id, "test, series") assert self.api.series_exists("testseries") is True def test_add_milestone(self): team_id = self.api.create_team("TestTeam") series_id = self.api.create_series("TestSeries", "A test series", team_id, "test, series") badge_id_1 = self.api.add_badge( "TestBadge-1", "TestImage-2", "A test badge for doing 10 unit tests", "TestCriteria", 1337 ) badge_id_2 = self.api.add_badge( "TestBadge-2", "TestImage-2", "A test badge for doing 100 unit tests", "TestCriteria", 1337 ) milestone_id_1 = self.api.create_milestone(1, badge_id_1, series_id) milestone_id_2 = self.api.create_milestone(2, badge_id_2, series_id) assert self.api.milestone_exists(milestone_id_1) is True assert self.api.milestone_exists(milestone_id_2) is True def test_add_person(self): self.api.add_person("*****@*****.**") assert self.api.person_exists("*****@*****.**") is True def test_add_issuer(self): _id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) assert self.api.issuer_exists("TestOrigin", "TestName") is True def test_add_invitation(self): badge_id = self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337 ) _id = self.api.add_invitation( badge_id, ) assert self.api.invitation_exists(_id) def test_last_login(self): email = "*****@*****.**" person_id = self.api.add_person(email) person = self.api.get_person(person_id) assert not person.last_login self.api.note_login(nickname=person.nickname) assert person.last_login def test_add_assertion(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) badge_id = self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) email = "*****@*****.**" person_id = self.api.add_person(email) assertion_id = self.api.add_assertion(badge_id, email, None, 'link') assert self.api.assertion_exists(badge_id, email) badge = self.api.get_badge(badge_id) assert badge.assertions[0].issued_for == 'link' # Ensure that we would have published two fedmsg messages for that. assert len(self.callback_calls) == 2 # Ensure that the first message had a 'badge_id' in the message. assert 'badge_id' in self.callback_calls[0][1]['msg']['badge'] def test_get_badges_from_tags(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) # Badge tagged with "test" self.api.add_badge( "TestBadgeA", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, tags="test" ) # Badge tagged with "tester" self.api.add_badge( "TestBadgeB", "TestImage", "A second test badge for doing unit tests", "TestCriteria", issuer_id, tags="tester" ) # Badge tagged with both "test" and "tester" self.api.add_badge( "TestBadgeC", "TestImage", "A third test badge for doing unit tests", "TestCriteria", issuer_id, tags="test, tester" ) tags = ['test', 'tester'] badges_any = self.api.get_badges_from_tags(tags, match_all=False) assert len(badges_any) == 3 badges_all = self.api.get_badges_from_tags(tags, match_all=True) assert len(badges_all) == 1 def tearDown(self): check_output(['rm', 'testdb.db']) self.callback_calls = []
from tahrir_api.dbapi import TahrirDatabase db = TahrirDatabase('backend://*****:*****@localhost/badges') origin = 'http://foss.rit.edu/badges' issuer_name = 'FOSS@RIT' org = 'http://foss.rit.edu' contact = '*****@*****.**' issuer_id = db.add_issuer(origin, issuer_name, org, contact) badge_name = 'fossbox' image = 'http://foss.rit.edu/files/fossboxbadge.png' desc = 'Welcome to the FOSSBox. A member is you!' criteria = 'http://foss.rit.edu' db.add_badge(badge_name, image, desc, criteria, issuer_id)
class TahrirRestApp(object): def __init__(self, dburi, salt): self.dburi = dburi self.salt = salt self.database = TahrirDatabase(self.dburi) self.app = Flask(__name__) self.routes = { "/badges/<uid>": (self.badges_uid, {'methods': ['GET', 'DELETE']}), "/badges/": (self.add_badge, {'methods': ['POST']}), "/people/<uid>": (self.people, {'methods': ['GET', 'DELETE']}), "/people/": (self.add_person, {'methods': ['POST']}), "/issuers/<uid>": (self.issuers, {'methods': ['GET', 'DELETE']}), "/issuers/": (self.add_issuer, {'methods': ['POST']}), "/assertions/<email>": (self.assertions, {'methods': ['GET']}), "/assertions/": (self.add_assertion, {'methods': ['POST']}), } map( lambda route: self.app.route(route, **self.routes[route][1])( self.routes[route][0] ), self.routes ) def people(self, uid): """ GET: /people/<uid> Delete: /people/<uid> Get info on a person, or delete them """ if request.method == 'DELETE': result = self.database.delete_person(uid) if result != False: log.info("DELETE Request for /people/{0} succeeded".format(uid)) return json.dumps({'success': True, 'id': result}) else: log.info("DELETE Request for /people/{0} failed",format(uid)) return json.dumps({'success': False, 'id': uid}) if request.method == 'GET': person = self.database.get_person(uid) if person == None: log.info("GET request for /people/{0} failed".format(uid)) return json.dumps({}) else: log.info("GET request for /people/{0} suceeded".format(uid)) return json.dumps(person.__json__()) def add_person(self): """ POST: /people/ Add a new Person """ try: data = json.loads(request.data) except: log.info("add_person Failed: could not parse request.data") abort(503) try: result = self.database.add_person( hash(data['email']), data['email'] ) log.info("Added Person: {0}".format(data['email'])) return json.dumps({'email': result}) except KeyError: log.info("add_person Failed: JSON doesn't include all required fields") abort(503) def badges_uid(self, uid): """ GET: /badges/<uid> DELETE: /badges/<uid> return s a JSON blob with all the badge attributes Deletes a badge with the given uid """ if request.method == 'DELETE': result = self.database.delete_badge(uid) if result != False: log.info("DELETE Request for /badges/{0} suceeded".format(uid)) return json.dumps({'success': True, 'id': result}) else: log.info("DELETE Request for /badges/{0} failed".format(uid)) return json.dumps({'success': False, 'id': uid}) if request.method == 'GET': badge = self.database.get_badge(uid) if badge == None: log.info("GET Request for /badges/{0} failed".format(uid)) return json.dumps({}) else: log.info("GET Request for /badges/{0} succeeded".format(uid)) return json.dumps(badge.__json__()) def add_badge(self): """ POST: /badges accepts a json blob with all the badge attributes """ try: data = json.loads(request.data) except: log.info("add_badge Failed: Could not parse request.data") abort(503) try: badge_id = self.database.add_badge( data['name'], data['image'], data['desc'], data['criteria'], data['issuer_id'] ) log.info("Added Badge: {0}".format(data['name'])) return json.dumps({'id': badge_id}) except KeyError: log.info("add_badge Failed: JSON does not have required fields") abort(503) def issuers(self, uid): """ GET /issuers/<id> DELETE /issuers/<id> Delete or Get an issuer """ if request.method == 'GET': issuer = self.database.get_issuer(uid) if issuer == None: log.info('GET Request for /issuers/{0} failed'.format(uid)) return json.dumps({}) else: log.info('Get Request for /issuers/{0} succeeded'.format(uid)) return json.dumps(issuer.__json__()) if request.method == 'DELETE': result = self.database.delete_issuer(uid) if result != False: log.info("DELETE Request for /issuers/{0} suceeded".format(uid)) return json.dumps({'success': True, 'id': uid}) else: log.info('DELETE Request for /issuers/{0} failed'.format(uid)) return json.dumps({'success': False, 'id': uid}) def add_issuer(self): """ POST /issuers/ Add a new issuer """ try: data = json.loads(request.data) except: log.info("add_issuer Failed: Could not parse request.data") abort(503) try: issuer_id = self.database.add_badge( data['origin'], data['name'], data['org'], data['contact'] ) log.info("Added issuer: {0}".format(data['name'])) return json.dumps({'id': issuer_id}) except KeyError: log.info("add_issuer Failed: JSON does not have required fields") abort(503) def assertions(self, email): """ GET /assertions/<email> Return a list of all assertions awarded to the given email """ results = self.database.get_assertions_by_email(email) if results == False: log.info("GET /assertions/{0} failed".format(email)) return json.dumps({"success": False, "email": email}) else: expanded_results = { 'success': True, 'assertions': [r.__json__() for r in results]} return json.dumps(expanded_results) def add_assertion(self): """ POST /assertions/ Add a new assertion """ try: data = json.loads(request.data) except: log.info("add_assertion Failed: Could not parse request.data") abort(503) try: person_email, badge_id = self.database.add_assertion( data['badge_id'], data['person_email'], data.get('issued_on', None) ) return json.dumps({ 'success': True, 'badge_id': badge_id, 'person_email': person_email }) except KeyError: log.info("add_assertion Failed: JSON does not have the required fields") abort(503)
from tahrir_api.dbapi import TahrirDatabase db = TahrirDatabase("backend://*****:*****@localhost/badges") origin = "http://foss.rit.edu/badges" issuer_name = "FOSS@RIT" org = "http://foss.rit.edu" contact = "*****@*****.**" issuer_id = db.add_issuer(origin, issuer_name, org, contact) badge_name = "fossbox" image = "http://foss.rit.edu/files/fossboxbadge.png" desc = "Welcome to the FOSSBox. A member is you!" criteria = "http://foss.rit.edu" db.add_badge(badge_name, image, desc, criteria, issuer_id)
class FedoraBadgesConsumer(FedmsgConsumer): """ The Base class for creating fedmsg consumers that issue open badges Provides a base that does all of the heavy lifting related to issuing badges. All the subclass needs to do is have a topic, a name, and implement consume(self, msg) :type hub: Moksha Hub :param hub: the moksha hub we are getting our messages from :type name: str :param name: name of this consumer, used to get details from the config file """ def __init__(self, hub, name): self.name = name self.badges = {} self.hub = hub self.DBSession = None ENABLED = 'fedmsg.consumers.badges.{0}.enabled'.format(self.name) if not asbool(hub.config.get(ENABLED, False)): log.info('fedmsg.consumers.badges.{0} disabled'.format(self.name)) return global_settings = hub.config.get("badges_global") database_uri = global_settings.get('database_uri', '') if database_uri == '': raise Exception('Badges consumer requires a database uri') return self.tahrir = TahrirDatabase(database_uri) self.DBSession = self.tahrir.session_maker issuer = global_settings.get('badge_issuer') self.issuer_id = self.tahrir.add_issuer(issuer.get('issuer_origin'), issuer.get('issuer_name'), issuer.get('issuer_org'), issuer.get('issuer_contact')) badges_settings = hub.config.get("{0}_badges".format(self.name)) for badge in badges_settings: self.tahrir.add_badge(badge.get('badge_name'), badge.get('badge_image'), badge.get('badge_desc'), badge.get('badge_criteria'), self.issuer_id) return super(FedoraBadgesConsumer, self).__init__(hub) def award_badge(self, email, badge_id, issued_on=None): """ A high level way to issue a badge to a Person It adds the person if they don't exist, and creates an assertion for them :type email: str :param email: This person's email addr :type badge_id: str :param badge_id: the id of the badge being awarded :type issued_on: DateTime :param issued_on: A datetime object with the time this badge was issued """ self.tahrir.add_person(email) self.tahrir.add_assertion(badge_id, email, issued_on) def consume(self, msg): """ Consume a single message, we pass here because every subclass is going to want to parse this slightly differently :type msg: dict :param msg: The message to be parsed """ pass
class TestDBInit(object): def setUp(self): check_output(['touch', 'testdb.db']) sqlalchemy_uri = "sqlite:///testdb.db" engine = create_engine(sqlalchemy_uri) DBSession.configure(bind=engine) DeclarativeBase.metadata.create_all(engine) self.callback_calls = [] self.api = TahrirDatabase(sqlalchemy_uri, notification_callback=self.callback) def callback(self, *args, **kwargs): self.callback_calls.append((args, kwargs)) def test_add_badges(self): self.api.add_badge("TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337) assert self.api.badge_exists("testbadge") is True def test_add_team(self): self.api.create_team("TestTeam") assert self.api.team_exists("testteam") is True def test_add_series(self): team_id = self.api.create_team("TestTeam") self.api.create_series("TestSeries", "A test series", team_id, "test, series") assert self.api.series_exists("testseries") is True def test_add_milestone(self): team_id = self.api.create_team("TestTeam") series_id = self.api.create_series("TestSeries", "A test series", team_id, "test, series") badge_id_1 = self.api.add_badge( "TestBadge-1", "TestImage-2", "A test badge for doing 10 unit tests", "TestCriteria", 1337) badge_id_2 = self.api.add_badge( "TestBadge-2", "TestImage-2", "A test badge for doing 100 unit tests", "TestCriteria", 1337) milestone_id_1 = self.api.create_milestone(1, badge_id_1, series_id) milestone_id_2 = self.api.create_milestone(2, badge_id_2, series_id) assert self.api.milestone_exists(milestone_id_1) is True assert self.api.milestone_exists(milestone_id_2) is True def test_add_person(self): self.api.add_person("*****@*****.**") assert self.api.person_exists("*****@*****.**") is True def test_add_issuer(self): _id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg", "TestContact") assert self.api.issuer_exists("TestOrigin", "TestName") is True def test_add_invitation(self): badge_id = self.api.add_badge("TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337) _id = self.api.add_invitation(badge_id, ) assert self.api.invitation_exists(_id) def test_last_login(self): email = "*****@*****.**" person_id = self.api.add_person(email) person = self.api.get_person(person_id) assert not person.last_login self.api.note_login(nickname=person.nickname) assert person.last_login def test_add_assertion(self): issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg", "TestContact") badge_id = self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) email = "*****@*****.**" person_id = self.api.add_person(email) assertion_id = self.api.add_assertion(badge_id, email, None, 'link') assert self.api.assertion_exists(badge_id, email) badge = self.api.get_badge(badge_id) assert badge.assertions[0].issued_for == 'link' # Ensure that we would have published two fedmsg messages for that. assert len(self.callback_calls) == 2 # Ensure that the first message had a 'badge_id' in the message. assert 'badge_id' in self.callback_calls[0][1]['msg']['badge'] def test_get_badges_from_tags(self): issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg", "TestContact") # Badge tagged with "test" self.api.add_badge("TestBadgeA", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, tags="test") # Badge tagged with "tester" self.api.add_badge("TestBadgeB", "TestImage", "A second test badge for doing unit tests", "TestCriteria", issuer_id, tags="tester") # Badge tagged with both "test" and "tester" self.api.add_badge("TestBadgeC", "TestImage", "A third test badge for doing unit tests", "TestCriteria", issuer_id, tags="test, tester") tags = ['test', 'tester'] badges_any = self.api.get_badges_from_tags(tags, match_all=False) assert len(badges_any) == 3 badges_all = self.api.get_badges_from_tags(tags, match_all=True) assert len(badges_all) == 1 def tearDown(self): check_output(['rm', 'testdb.db']) self.callback_calls = []
class TestRanking(object): def setUp(self): check_output(['touch', 'testdb.db']) sqlalchemy_uri = "sqlite:///testdb.db" engine = create_engine(sqlalchemy_uri) DBSession.configure(bind=engine) DeclarativeBase.metadata.create_all(engine) self.api = TahrirDatabase(sqlalchemy_uri) self._create_test_data() def tearDown(self): check_output(['rm', 'testdb.db']) def _create_test_data(self): issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg", "TestContact") self.badge_id_1 = self.api.add_badge( "TestBadge1", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.badge_id_2 = self.api.add_badge( "TestBadge2", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.badge_id_3 = self.api.add_badge( "TestBadge3", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) self.email_1 = "*****@*****.**" person_id_1 = self.api.add_person(self.email_1) self.email_2 = "*****@*****.**" person_id_2 = self.api.add_person(self.email_2) self.email_3 = "*****@*****.**" person_id_3 = self.api.add_person(self.email_3) self.email_4 = "*****@*****.**" person_id_4 = self.api.add_person(self.email_4) def test_ranking_simple(self): self.api.add_assertion(self.badge_id_1, self.email_1, None) self.api.add_assertion(self.badge_id_1, self.email_4, None) self.api.add_assertion(self.badge_id_2, self.email_4, None) self.api.add_assertion(self.badge_id_3, self.email_4, None) person1 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") eq_(person1.rank, 2) eq_(person4.rank, 1) def test_ranking_tie(self): self.api.add_assertion(self.badge_id_1, self.email_1, None) self.api.add_assertion(self.badge_id_1, self.email_2, None) self.api.add_assertion(self.badge_id_2, self.email_2, None) self.api.add_assertion(self.badge_id_1, self.email_3, None) self.api.add_assertion(self.badge_id_2, self.email_3, None) self.api.add_assertion(self.badge_id_1, self.email_4, None) self.api.add_assertion(self.badge_id_2, self.email_4, None) self.api.add_assertion(self.badge_id_3, self.email_4, None) person1 = self.api.get_person("*****@*****.**") person2 = self.api.get_person("*****@*****.**") person3 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") eq_(person1.rank, 4) eq_(person2.rank, 2) eq_(person3.rank, 2) eq_(person4.rank, 1) def test_ranking_preexisting(self): """ Test that rank updating works for pre-existant users """ person1 = self.api.get_person("*****@*****.**") new_assertion1 = Assertion( badge_id=self.badge_id_1, person_id=person1.id, ) self.api.session.add(new_assertion1) new_assertion2 = Assertion( badge_id=self.badge_id_2, person_id=person1.id, ) self.api.session.add(new_assertion2) self.api.session.flush() # For persons who existed *before* we added cached ranks, they should # have a null-rank. eq_(person1.rank, None) # But once *anyone* else gets a badge, old ranks should be updated too. self.api.add_assertion(self.badge_id_1, self.email_2, None) eq_(person1.rank, 1) person2 = self.api.get_person("*****@*****.**") eq_(person2.rank, 2) # but people with no badges should still be null ranked. person3 = self.api.get_person("*****@*****.**") eq_(person3.rank, None) def test_ranking_with_time_limits(self): self.api.add_assertion(self.badge_id_1, self.email_1, yesterday) self.api.add_assertion(self.badge_id_1, self.email_4, yesterday) self.api.add_assertion(self.badge_id_2, self.email_4, one_week_ago) self.api.add_assertion(self.badge_id_3, self.email_4, one_month_ago) person1 = self.api.get_person("*****@*****.**") person4 = self.api.get_person("*****@*****.**") epsilon = datetime.timedelta(hours=1) results = self.api._make_leaderboard(yesterday - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 1) results = self.api._make_leaderboard(one_week_ago - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 2) results = self.api._make_leaderboard(one_month_ago - epsilon, now) eq_(results[person1]['badges'], 1) eq_(results[person4]['badges'], 3)
class TestDBInit(object): def setUp(self): check_output(['touch', 'testdb.db']) sqlalchemy_uri = "sqlite:///testdb.db" engine = create_engine(sqlalchemy_uri) DBSession.configure(bind=engine) DeclarativeBase.metadata.create_all(engine) self.api = TahrirDatabase(sqlalchemy_uri) def test_add_badges(self): self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337 ) assert self.api.badge_exists("testbadge") is True def test_add_person(self): self.api.add_person("*****@*****.**") assert self.api.person_exists("*****@*****.**") is True def test_add_issuer(self): _id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) assert self.api.issuer_exists("TestOrigin", "TestName") is True def test_add_invitation(self): badge_id = self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", 1337 ) _id = self.api.add_invitation( badge_id, ) assert self.api.invitation_exists(_id) def test_last_login(self): email = "*****@*****.**" person_id = self.api.add_person(email) person = self.api.get_person(person_id) assert not person.last_login self.api.note_login(nickname=person.nickname) assert person.last_login def test_add_assertion(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) badge_id = self.api.add_badge( "TestBadge", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, ) email = "*****@*****.**" person_id = self.api.add_person(email) assertion_id = self.api.add_assertion(badge_id, email, None) assert self.api.assertion_exists(badge_id, email) def test_get_badges_from_tags(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" ) # Badge tagged with "test" self.api.add_badge( "TestBadgeA", "TestImage", "A test badge for doing unit tests", "TestCriteria", issuer_id, tags="test" ) # Badge tagged with "tester" self.api.add_badge( "TestBadgeB", "TestImage", "A second test badge for doing unit tests", "TestCriteria", issuer_id, tags="tester" ) # Badge tagged with both "test" and "tester" self.api.add_badge( "TestBadgeC", "TestImage", "A third test badge for doing unit tests", "TestCriteria", issuer_id, tags="test, tester" ) tags = ['test', 'tester'] badges_any = self.api.get_badges_from_tags(tags, match_all=False) assert len(badges_any) == 3 badges_all = self.api.get_badges_from_tags(tags, match_all=True) assert len(badges_all) == 1 def tearDown(self): check_output(['rm', 'testdb.db'])