def create(self, request, *args, **kwargs): if self.request.data.get('about_type') == "mission": mission = Mission.get(self.kwargs[self.lookup_field]) quest = Quest.get(mission.owner_username) if quest is None: return Response( { "status_code": status.HTTP_404_NOT_FOUND, "detail": "Sorry we couldn't find the Quest you were " "attempting to create an update for." }, status=status.HTTP_404_NOT_FOUND) if quest.owner_username == request.user.username: return super(UpdateListCreate, self).create(request, *args, **kwargs) if request.user.username not in \ Quest.get_quest_helpers(self.kwargs[self.lookup_field]): return Response( { "status_code": status.HTTP_403_FORBIDDEN, "detail": "You are not authorized to access " "this page." }, status=status.HTTP_403_FORBIDDEN) return super(UpdateListCreate, self).create(request, *args, **kwargs)
def perform_create(self, serializer): object_uuid = str(uuid1()) if self.request.data.get('about_type') == "mission" \ or 'mission' in self.request.path: about = Mission.get(self.kwargs[self.lookup_field]) quest = Quest.get(about.owner_username) url = reverse('mission_updates', kwargs={ 'object_uuid': self.kwargs[self.lookup_field], 'slug': slugify(about.get_mission_title()) }, request=self.request) else: # If all else fails assume this update is about the Quest itself quest = Quest.get(self.kwargs[self.lookup_field]) # TODO update quest url generation when we have an updates for # quest url = None about = quest serializer.save(quest=quest, about=about, url=url, object_uuid=object_uuid, href=reverse('update-detail', kwargs={'object_uuid': object_uuid}, request=self.request))
def setUp(self): self.email = "*****@*****.**" create_user_util_test(self.email) self.owner = Pleb.nodes.get(email=self.email) self.quest = Quest(owner_username=self.owner.username, object_uuid=str(uuid1())).save() self.quest.owner.connect(self.owner)
def setUp(self): settings.CELERY_ALWAYS_EAGER = True self.email = "*****@*****.**" create_user_util_test(self.email) self.pleb = Pleb.nodes.get(email=self.email) self.user = User.objects.get(email=self.email) self.quest = Quest(owner_username=self.pleb.username, object_uuid=str(uuid1())).save() self.quest.owner.connect(self.pleb)
def test_get_mission(self): quest = Quest(owner_username=self.pleb.username).save() quest.owner.connect(self.pleb) mission = Mission(owner_username=self.pleb.username).save() quest.missions.connect(mission) mission.associated_with.connect(self.question) res = Question.get_mission(self.question.object_uuid) self.assertEqual(res['id'], mission.object_uuid) mission.delete() quest.delete()
def setUp(self): query = 'MATCH (a) OPTIONAL MATCH (a)-[r]-() DELETE a, r' db.cypher_query(query) self.email = "*****@*****.**" self.password = "******" self.pleb = create_user_util_test(self.email) self.user = User.objects.get(email=self.email) self.pleb.email_verified = True self.pleb.save() cache.clear() self.mission = Mission(owner_username=self.user.username, title=str(uuid1())).save() self.quest = Quest(owner_username=self.pleb.username).save() self.quest.missions.connect(self.mission) self.quest.owner.connect(self.pleb)
def list(self, request, *args, **kwargs): """ Currently we limit this endpoint to only be accessible to owners/accountants of campaigns, this is because it displays all donations not just the completed ones. We will eventually want to add some functionality to this that will allow people who are not the owner/accountant of the campaign to view all completed donations. :param request: :param args: :param kwargs: :return: """ if "mission" in self.request.path: moderators = Mission.get( object_uuid=self.kwargs[self.lookup_field]) else: moderators = Quest.get( owner_username=self.kwargs[self.lookup_field]) if not (request.user.username in moderators.get_moderators( moderators.owner_username)): return Response( { "status_code": status.HTTP_403_FORBIDDEN, "detail": "You are not authorized to access " "this page." }, status=status.HTTP_403_FORBIDDEN) return super(DonationListCreate, self).list(request, *args, **kwargs)
def test_get_can_downvote_mission_owner(self): quest = Quest(owner_username=self.pleb.username).save() quest.owner.connect(self.pleb) mission = Mission(owner_username=self.pleb.username).save() quest.missions.connect(mission) question = Question(content='test content title', title=str(uuid1())).save() mission.associated_with.connect(question) factory = APIRequestFactory() request = factory.get('') request.user = self.user res = VotableContentSerializer( question, context={'request': request}).data self.assertTrue(res['can_downvote']['status']) mission.delete() quest.delete()
def mission_updates(request, object_uuid, slug=None): # Only need to check that at least one update exists here to mark that # updates are available for this mission. query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \ '(mission:Mission {object_uuid: "%s"}) ' \ 'WITH quest, mission ' \ 'OPTIONAL MATCH (mission)<-[:ABOUT]-(updates:Update) ' \ 'RETURN quest, mission, ' \ 'CASE WHEN count(updates) > 0 ' \ 'THEN true ELSE false END AS update' % object_uuid res, _ = db.cypher_query(query) if res.one is None: return redirect("404_Error") # Instead of doing inflation and serialization of all the updates here # without pagination lets just indicate if we have any or not and then # hit the endpoint to gather the actual updates. quest = Quest.inflate(res.one.quest) mission_obj = Mission.inflate(res.one.mission) return render( request, 'mission/updates.html', { "updates": res.one.update, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "slug": slugify(mission_obj.get_mission_title()), "quest": QuestSerializer(quest).data })
def mission_endorsements(request, object_uuid, slug=None): # Just check if there are any endorsements either from a Pleb or a Quest query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \ '(mission:Mission {object_uuid:"%s"}) ' \ 'WITH quest, mission ' \ 'OPTIONAL MATCH (mission)<-[:ENDORSES]-(endorsement) ' \ 'RETURN endorsement, quest, mission' % object_uuid res, _ = db.cypher_query(query) # Instead of doing inflation and serialization of all the updates here # without pagination lets just indicate if we have any or not and then # hit the endpoint to gather the actual updates. quest = Quest.inflate(res.one.quest) mission_obj = Mission.inflate(res.one.mission) return render( request, 'mission/endorsements.html', { "quest": QuestSerializer(quest).data, "mission": MissionSerializer(mission_obj, context={ "request": request }).data, "slug": slugify(mission_obj.get_mission_title()), "endorsements": True if res.one.endorsement else False })
def setUp(self): query = "MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r" db.cypher_query(query) cache.clear() self.unit_under_test_name = 'quest' self.email = "*****@*****.**" self.pleb = create_user_util_test(self.email) self.user = User.objects.get(email=self.email) self.url = "http://testserver" self.quest = Quest(about='Test Bio', owner_username=self.pleb.username).save() self.quest.editors.connect(self.pleb) self.quest.moderators.connect(self.pleb) self.address = Address(street="125 Glenwood Drive", city="Walled Lake", state="Michigan", postal_code="48390", country="USA", county="Oakland", congressional_district=11, validated=True).save() self.quest.address.connect(self.address) cache.clear() self.mission = Mission(owner_username=self.pleb.username, title=str(uuid1()), focus_name="advocacy", location_name="11").save() self.quest.missions.connect(self.mission) self.giftlist = self.mission.get_giftlist() if not self.giftlist: self.giftlist = Giftlist().save() self.giftlist.mission.connect(self.mission) self.email2 = "*****@*****.**" self.pleb2 = create_user_util_test(self.email2) self.user2 = User.objects.get(email=self.email2)
def setUp(self): cache.clear() self.unit_under_test_name = 'goal' self.email = "*****@*****.**" self.pleb = create_user_util_test(self.email) self.user = User.objects.get(email=self.email) self.email2 = "*****@*****.**" self.pleb2 = create_user_util_test(self.email2) self.user2 = User.objects.get(email=self.email2) self.url = "http://testserver" self.quest = Quest( about='Test Bio', owner_username=self.pleb.username).save() self.quest.editors.connect(self.pleb) self.quest.moderators.connect(self.pleb) cache.clear() self.stripe = stripe self.stripe.api_key = settings.STRIPE_SECRET_KEY self.stripe.api_version = settings.STRIPE_API_VERSION self.mission = Mission(owner_username=self.pleb.username, title=str(uuid1()), focus_name="advocacy").save() self.volunteer = Volunteer(activities=["get_out_the_vote"], mission_id=self.mission.object_uuid, owner_username=self.pleb2.username).save() self.quest.missions.connect(self.mission) self.volunteer.mission.connect(self.mission) self.volunteer.volunteer.connect(self.pleb2)
def remove_duplicate_quests(self): skip = 0 while True: query = 'MATCH (official:PublicOfficial) ' \ 'RETURN DISTINCT official ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break for official in [PublicOfficial.inflate(row[0]) for row in res]: query = 'MATCH (official:PublicOfficial {object_uuid:"%s"})-' \ '[:IS_HOLDING]->(a:Quest) ' \ 'OPTIONAL MATCH (a)-[r]-() ' \ 'DELETE a, r' % official.object_uuid db.cypher_query(query) quest = Quest(about=official.bio, youtube=official.youtube, twitter=official.twitter, website=official.website, first_name=official.first_name, last_name=official.last_name, owner_username=official.object_uuid, title="%s %s" % (official.first_name, official.last_name), profile_pic="%s/representative_images/225x275/" "%s.jpg" % (settings.LONG_TERM_STATIC_DOMAIN, official.bioguideid)).save() official.quest.connect(quest) cache.set(self.cache_key, True)
class TestCheckUnverifiedQuest(TestCase): def setUp(self): settings.CELERY_ALWAYS_EAGER = True self.email = "*****@*****.**" create_user_util_test(self.email) self.pleb = Pleb.nodes.get(email=self.email) self.user = User.objects.get(email=self.email) self.quest = Quest(owner_username=self.pleb.username, object_uuid=str(uuid1())).save() self.quest.owner.connect(self.pleb) def tearDown(self): settings.CELERY_ALWAYS_EAGER = False @requests_mock.mock() def test_less_than_three_days(self, m): m.post("https://api.intercom.io/events/", json={ "event_name": "unverified-quest", "user_id": self.quest.owner_username }, status_code=status.HTTP_202_ACCEPTED) now = datetime.now(pytz.utc) self.quest.account_first_updated = now self.quest.save() res = check_unverified_quest.apply_async() while not res.ready(): time.sleep(1) self.assertTrue(res.result) @requests_mock.mock() def test_greater_than_three_days(self, m): m.post("https://api.intercom.io/events/", json={ "event_name": "still-unverified-quest", "user_id": self.quest.owner_username }, status_code=status.HTTP_202_ACCEPTED) past = datetime.now(pytz.utc) - relativedelta(days=4) self.quest.account_first_updated = past self.quest.account_verified = "unverified" self.quest.save() res = check_unverified_quest.apply_async() while not res.ready(): time.sleep(1) self.assertTrue(res.result)
def repopulate_elasticsearch(self): # Profiles skip = 0 while True: query = 'MATCH (profile:Pleb) RETURN DISTINCT profile ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break for profile in [Pleb.inflate(row[0]) for row in res]: update_search_object.apply_async(kwargs={ "object_uuid": profile.object_uuid, "label": "pleb" }) # Questions skip = 0 while True: query = 'MATCH (question:Question) RETURN DISTINCT question ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break for question in [Question.inflate(row[0]) for row in res]: update_search_object.apply_async(kwargs={ "object_uuid": question.object_uuid, "label": "question" }) # Quests skip = 0 while True: query = 'MATCH (quest:Quest) RETURN DISTINCT quest ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break for quest in [Quest.inflate(row[0]) for row in res]: update_search_object.apply_async(kwargs={ "object_uuid": quest.object_uuid, "label": "quest" }) # Missions skip = 0 while True: query = 'MATCH (mission:Mission) RETURN DISTINCT mission ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break for mission in [Mission.inflate(row[0]) for row in res]: update_search_object.apply_async(kwargs={ "object_uuid": mission.object_uuid, "label": "mission" })
def test_get_donations(self): donation = Donation(amount=100).save() mission = Mission().save() self.quest.missions.connect(mission) donation.mission.connect(mission) donation.quest.connect(self.quest) res = Quest.get_donations(self.quest.owner_username) self.assertEqual(donation.object_uuid, res[0].object_uuid)
class TestOrderTasks(TestCase): def setUp(self): query = 'MATCH (a) OPTIONAL MATCH (a)-[r]-() DELETE a, r' db.cypher_query(query) self.email = "*****@*****.**" self.password = "******" self.pleb = create_user_util_test(self.email) self.user = User.objects.get(email=self.email) self.pleb.email_verified = True self.pleb.save() cache.clear() self.mission = Mission(owner_username=self.user.username, title=str(uuid1())).save() self.quest = Quest(owner_username=self.pleb.username).save() self.quest.missions.connect(self.mission) self.quest.owner.connect(self.pleb) def test_uncompleted_sort(self): setup_onboarding(self.quest, self.mission) db.cypher_query('MATCH (a:OnboardingTask {title: "Mission Setup"}) ' 'SET a.completed=False RETURN a') uncompleted_sort, completed_count = order_tasks( self.mission.object_uuid) self.assertEqual(len(uncompleted_sort), len(settings.ONBOARDING_TASKS)) for item in range(0, len(settings.ONBOARDING_TASKS) - 1): self.assertEqual(uncompleted_sort[item]['priority'], item + 1) def test_completed_sort_none_completed(self): setup_onboarding(self.quest, self.mission) db.cypher_query('MATCH (a:OnboardingTask {title: "Mission Setup"}) ' 'SET a.completed=False RETURN a') uncompleted_sort, completed_count = order_tasks( self.mission.object_uuid) self.assertEqual(completed_count, 0) def test_completed_sort_one_completed(self): self.quest.account_verified = "verified" self.quest.save() setup_onboarding(self.quest, self.mission) db.cypher_query('MATCH (a:OnboardingTask {title: "Mission Setup"}) ' 'SET a.completed=False RETURN a') uncompleted_sort, completed_count = order_tasks( self.mission.object_uuid) self.assertEqual(completed_count, 1) self.assertTrue( uncompleted_sort[len(uncompleted_sort) - 1]['completed'])
def set_quest_titles(self): query = 'MATCH (a:Quest) WHERE a.title IS NULL RETURN a' res, _ = db.cypher_query(query) for quest in [Quest.inflate(row[0]) for row in res]: quest.title = "%s %s" % (quest.first_name, quest.last_name) quest.save() cache.delete("%s_quest" % quest.object_uuid) self.stdout.write("completed quest titles\n", ending='')
def has_object_permission(self, request, view, obj): if request.user.username in \ Quest.get_moderators(owner_username=obj) or \ request.user.username == obj or request.user.username in \ Mission.get_moderators(owner_username=obj): return True else: return False
def mission_account_signup(request): try: quest = Quest.get(owner_username=request.user.username) except (Mission.DoesNotExist, DoesNotExist): return redirect("404_Error") except (CypherException, ClientError, IOError): # pragma: no cover return redirect("500_Error") return render(request, 'mission/account_setup.html', {"quest": quest})
def get_quest(self, obj): request, expand, _, _, _ = gather_request_data( self.context, expand_param=self.context.get('expand', None)) try: quest = Quest.get(owner_username=obj.username) except(Quest.DoesNotExist, DoesNotExist): return None if expand == 'true' and quest is not None: return QuestSerializer(quest, context={'request': request}).data return quest.owner_username
def endorsements(self, request, object_uuid=None): serialized = [] endorsements = Mission.get_endorsements(object_uuid) page = self.paginate_queryset(endorsements) for node in page: if "Pleb" in node.labels: serialized.append(PlebSerializerNeo(Pleb.inflate(node.e)).data) if "Quest" in node.labels: serialized.append(QuestSerializer(Quest.inflate(node.e)).data) return self.get_paginated_response(serialized)
def test_create_with_mission(self): from sb_quests.neo_models import Quest from sb_missions.neo_models import Mission self.client.force_authenticate(user=self.user) url = reverse("question-solutions", kwargs={'object_uuid': self.question.object_uuid}) quest = Quest(owner_username=self.pleb.username).save() quest.owner.connect(self.pleb) mission = Mission(owner_username=self.pleb.username).save() quest.missions.connect(mission) mission.associated_with.connect(self.question) data = { "question": self.question.object_uuid, "content": self.solution.content } response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) mission.delete() quest.delete()
def setUp(self): self.factory = APIRequestFactory() self.client = Client() self.email = "*****@*****.**" self.password = "******" self.pleb = create_user_util_test(self.email) self.user = User.objects.get(email=self.email) self.email2 = "*****@*****.**" self.pleb2 = create_user_util_test(self.email2) self.user2 = User.objects.get(email=self.email2) self.pleb.email_verified = True self.pleb.save() cache.clear() self.mission = Mission(owner_username=self.user.username, title=str(uuid1())).save() self.quest = Quest(owner_username=self.pleb.username).save() self.quest2 = Quest(owner_username=self.pleb2.username).save() self.quest.missions.connect(self.mission) self.quest.owner.connect(self.pleb)
def get_quest(self, obj): from sb_quests.neo_models import Quest from sb_quests.serializers import QuestSerializer request, _, _, _, _ = gather_request_data(self.context) query = 'MATCH (quest:Quest)-[:EMBARKS_ON]->' \ '(:Mission {object_uuid: "%s"}) RETURN quest' % obj.object_uuid res, _ = db.cypher_query(query) if res.one is None: return None return QuestSerializer(Quest.inflate(res.one), context={'request': request}).data
def get_about(self, obj): from sb_missions.neo_models import Mission from sb_missions.serializers import MissionSerializer from sb_quests.neo_models import Quest from sb_quests.serializers import QuestSerializer if obj.about_type == "mission": return MissionSerializer(Mission.get(obj.about_id)).data elif obj.about_type == "quest": return QuestSerializer(Quest.get(obj.about_id)).data else: return None
def setUp(self): db.cypher_query('MATCH (a) OPTIONAL MATCH (a)-[r]-() DELETE a, r') self.factory = APIRequestFactory() self.client = Client() self.email = "*****@*****.**" self.password = "******" create_user_util_test(self.email) self.pleb = Pleb.nodes.get(email=self.email) self.user = User.objects.get(email=self.email) self.pleb.email_verified = True self.pleb.save() cache.clear() self.mission = Mission(owner_username=self.user.username, title=str(uuid1()), focus_on_type="advocacy", focus_name="testing advocacy", district=None).save() self.quest = Quest(owner_username=self.pleb.username).save() self.quest.missions.connect(self.mission) self.quest.owner.connect(self.pleb) setup_onboarding(self.quest, self.mission)
def get_moderators(cls, owner_username): from sb_quests.neo_models import Quest quest = Quest.get(owner_username) moderators = cache.get("%s_moderators" % quest.owner_username) if moderators is None: query = 'MATCH (quest:Quest {owner_username: "******"})<-' \ '[:MODERATOR_OF]-(pleb:Pleb) ' \ 'RETURN pleb.username' % owner_username res, col = db.cypher_query(query) moderators = [row[0] for row in res] cache.set("%s_moderators" % quest.owner_username, moderators) return moderators
def get_search_html(request, object_uuid): try: quest = Quest.get(object_uuid) except (CypherException, IOError): return Response('Server Error', status=500) rendered_html = render_to_string( "saga_search_block.html", QuestSerializer(quest, context={ 'request': request }).data) return Response({'html': rendered_html}, status=200)
def convert_social_links(self): twitter_string = "https://www.twitter.com/" facebook_string = "https://www.facebook.com/" linkedin_string = "https://www.linkedin.com/in/" youtube_string = "https://www.youtube.com/user/" skip = 0 while True: query = 'MATCH (q:Quest) RETURN q ' \ 'SKIP %s LIMIT 25' % skip skip += 24 res, _ = db.cypher_query(query) if not res.one: break try: for quest in [Quest.inflate(row[0]) for row in res]: if quest.twitter and twitter_string not in quest.twitter: quest.twitter = "%s%s" % (twitter_string, quest.twitter) if quest.facebook and facebook_string not in quest.facebook: quest.facebook = "%s%s" % (facebook_string, quest.facebook) if quest.linkedin and linkedin_string not in quest.linkedin: quest.linkedin = "%s%s" % (linkedin_string, quest.linkedin) if quest.youtube and youtube_string not in quest.youtube: quest.youtube = "%s%s" % (youtube_string, quest.youtube) quest.save() cache.delete("%s_quest" % quest.object_uuid) except (CypherException, Exception): logger.exception("Convert Social Links: ") pass try: res, _ = db.cypher_query('MATCH (a:Mission) RETURN a') for mission in [Mission.inflate(row[0]) for row in res]: if mission.twitter and twitter_string not in mission.twitter: mission.twitter = "%s%s" % (twitter_string, mission.twitter) if mission.facebook and facebook_string not in mission.facebook: mission.facebook = "%s%s" % (facebook_string, mission.facebook) if mission.linkedin and linkedin_string not in mission.linkedin: mission.linkedin = "%s%s" % (linkedin_string, mission.linkedin) if mission.youtube and youtube_string not in mission.youtube: mission.youtube = "%s%s" % (youtube_string, mission.youtube) mission.save() cache.delete("%s_mission" % mission.object_uuid) except (CypherException, Exception): logger.exception("Convert Social Links: ") pass