· 4 years ago · Mar 04, 2021, 02:54 AM
1diff -r COPY/.git/HEAD cardway_backend/.git/HEAD
21c1
3< 4b320895c696d11490d1e42e81d801b1343f49b1
4---
5> ref: refs/heads/event_management
6Binary files COPY/.git/index and cardway_backend/.git/index differ
7diff -r COPY/.git/logs/HEAD cardway_backend/.git/logs/HEAD
8231a232
9> 4b320895c696d11490d1e42e81d801b1343f49b1 c33194ef6983b7b2a13769b519d709e5cff7cff3 astherath <farceriv@gmail.com> 1614826043 -0500 checkout: moving from 4b320895c696d11490d1e42e81d801b1343f49b1 to event_management
10diff -r COPY/Procfile cardway_backend/Procfile
111c1
12< web: sh prod.sh
13---
14> web: sh prod.sh
15Binary files COPY/config/__pycache__/main.cpython-39.pyc and cardway_backend/config/__pycache__/main.cpython-39.pyc differ
16diff -r COPY/config/main.py cardway_backend/config/main.py
171,16c1,16
18< """
19< Main configuration and instance-sharing file for the modules.
20< Mainly instanciates the FastAPI `app` object and
21< sets some environment variables.
22< """
23< import os
24<
25<
26< def is_testing():
27< return os.environ.get("_called_from_test") == "True"
28<
29<
30< DB_URI = os.environ["CARDWAY_DB_URI"]
31< AUTH_SECRET_KEY = os.environ["CARDWAY_AUTH_SECRET_KEY"]
32< AUTH_ALGORITHM = "HS256"
33< JWT_SUBJECT = "access"
34---
35> """
36> Main configuration and instance-sharing file for the modules.
37> Mainly instanciates the FastAPI `app` object and
38> sets some environment variables.
39> """
40> import os
41>
42>
43> def is_testing():
44> return os.environ.get("_called_from_test") == "True"
45>
46>
47> DB_URI = os.environ["CARDWAY_DB_URI"]
48> AUTH_SECRET_KEY = os.environ["CARDWAY_AUTH_SECRET_KEY"]
49> AUTH_ALGORITHM = "HS256"
50> JWT_SUBJECT = "access"
51diff -r COPY/docs/business.py cardway_backend/docs/business.py
521,5c1,5
53< # pylint: skip-file
54< register_business_description = """
55< Registers a business given the business data form. Returns the registered business_id if successful.
56< """
57< register_business_summary = "Register Business"
58---
59> # pylint: skip-file
60> register_business_description = """
61> Registers a business given the business data form. Returns the registered business_id if successful.
62> """
63> register_business_summary = "Register Business"
64diff -r COPY/docs/events.py cardway_backend/docs/events.py
651,5c1,5
66< # pylint: skip-file
67< register_event_description = """
68< Registers an event given the event data form. Returns the registered event_id if successful.
69< """
70< register_event_summary = "Register Event"
71---
72> # pylint: skip-file
73> register_event_description = """
74> Registers an event given the event data form. Returns the registered event_id if successful.
75> """
76> register_event_summary = "Register Event"
77Binary files COPY/endpoints/__pycache__/business.cpython-39.pyc and cardway_backend/endpoints/__pycache__/business.cpython-39.pyc differ
78diff -r COPY/endpoints/business.py cardway_backend/endpoints/business.py
791,36c1,36
80< """
81< Router for all of the business-related endpoints.
82<
83< Should only really delegate to other modules and function handlers, as keeping
84< code here would be an absolute mess.
85< """
86<
87< from fastapi import APIRouter
88< import graphene
89< from graphql.execution.executors.asyncio import AsyncioExecutor
90< from starlette.graphql import GraphQLApp
91<
92< from models import business as models
93< from models.graphql import business as graphql_models
94< from utils import business as utils
95< from docs import business as docs
96<
97< router = APIRouter()
98< ROUTE_TAG = "Business"
99<
100< router.add_route(
101< "/business/graphql",
102< GraphQLApp(schema=graphene.Schema(query=graphql_models.Query,
103< mutation=graphql_models.Mutation),
104< executor_class=AsyncioExecutor))
105<
106<
107< @router.post("/business/register",
108< response_model=models.BusinessRegistrationResponse,
109< description=docs.register_business_description,
110< summary=docs.register_business_summary,
111< tags=[ROUTE_TAG],
112< status_code=201)
113< async def register_business(form: models.BusinessRegistrationForm):
114< business_id = await utils.register_business(form)
115< return models.BusinessRegistrationResponse(business_id=business_id)
116---
117> """
118> Router for all of the business-related endpoints.
119>
120> Should only really delegate to other modules and function handlers, as keeping
121> code here would be an absolute mess.
122> """
123>
124> from fastapi import APIRouter
125> import graphene
126> from graphql.execution.executors.asyncio import AsyncioExecutor
127> from starlette.graphql import GraphQLApp
128>
129> from models import business as models
130> from models.graphql import business as graphql_models
131> from utils import business as utils
132> from docs import business as docs
133>
134> router = APIRouter()
135> ROUTE_TAG = "Business"
136>
137> router.add_route(
138> "/business/graphql",
139> GraphQLApp(schema=graphene.Schema(query=graphql_models.Query,
140> mutation=graphql_models.Mutation),
141> executor_class=AsyncioExecutor))
142>
143>
144> @router.post("/business/register",
145> response_model=models.BusinessRegistrationResponse,
146> description=docs.register_business_description,
147> summary=docs.register_business_summary,
148> tags=[ROUTE_TAG],
149> status_code=201)
150> async def register_business(form: models.BusinessRegistrationForm):
151> business_id = await utils.register_business(form)
152> return models.BusinessRegistrationResponse(business_id=business_id)
153Only in cardway_backend/: get-pip.py
154diff -r COPY/models/__init__.py cardway_backend/models/__init__.py
1551,12c1,12
156< """
157< Explicit module declaration for the models.
158<
159< Code will run fine without this,
160< but pytest complains enough to do this.
161< """
162< import models.business
163< import models.commons
164< import models.events
165< import models.exceptions
166< import models.posts
167< import models.users
168---
169> """
170> Explicit module declaration for the models.
171>
172> Code will run fine without this,
173> but pytest complains enough to do this.
174> """
175> import models.business
176> import models.commons
177> import models.events
178> import models.exceptions
179> import models.posts
180> import models.users
181Binary files COPY/models/__pycache__/__init__.cpython-39.pyc and cardway_backend/models/__pycache__/__init__.cpython-39.pyc differ
182Binary files COPY/models/__pycache__/business.cpython-39.pyc and cardway_backend/models/__pycache__/business.cpython-39.pyc differ
183Binary files COPY/models/__pycache__/commons.cpython-39.pyc and cardway_backend/models/__pycache__/commons.cpython-39.pyc differ
184Binary files COPY/models/__pycache__/events.cpython-39.pyc and cardway_backend/models/__pycache__/events.cpython-39.pyc differ
185diff -r COPY/models/business.py cardway_backend/models/business.py
1861,31c1,31
187< # pylint: disable=E1136; see https://github.com/PyCQA/pylint/issues/3882
188< # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
189< """
190< Holds models that relate to how the business is represented in the database,
191< as well as all of the incoming/validated forms for the endpoint code.
192< """
193< from typing import Optional
194< from uuid import uuid4
195< from pydantic import BaseModel, Field
196< from models.commons import UserAccount, Location
197<
198<
199< class BusinessRegistrationForm(UserAccount):
200< business_name: str
201< business_tag: str
202< tagline: Optional[str]
203< description: str
204< website_url: str
205< hours_of_operation: str
206< max_occupancy: Optional[str]
207< menu_link: Optional[str]
208< delivery_link: str
209<
210<
211< class Business(BusinessRegistrationForm):
212< id: str = Field(str(uuid4()), alias='_id') # pylint: disable=invalid-name
213< location: Location
214<
215<
216< class BusinessRegistrationResponse(BaseModel):
217< business_id: str
218---
219> # pylint: disable=E1136; see https://github.com/PyCQA/pylint/issues/3882
220> # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
221> """
222> Holds models that relate to how the business is represented in the database,
223> as well as all of the incoming/validated forms for the endpoint code.
224> """
225> from typing import Optional
226> from uuid import uuid4
227> from pydantic import BaseModel, Field
228> from models.commons import UserAccount, Location
229>
230>
231> class BusinessRegistrationForm(UserAccount):
232> business_name: str
233> business_tag: str
234> tagline: Optional[str]
235> description: str
236> website_url: str
237> hours_of_operation: str
238> max_occupancy: Optional[str]
239> menu_link: Optional[str]
240> delivery_link: str
241>
242>
243> class Business(BusinessRegistrationForm):
244> id: str = Field(str(uuid4()), alias='_id') # pylint: disable=invalid-name
245> location: Location
246>
247>
248> class BusinessRegistrationResponse(BaseModel):
249> business_id: str
250diff -r COPY/models/comments.py cardway_backend/models/comments.py
2511,31c1,31
252< # pylint: disable=E1136; see https://github.com/PyCQA/pylint/issues/3882
253< # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
254< # Pydantic specific naming for the next couple of linter disables
255< # pylint: disable=no-self-argument
256< # pylint: disable=no-self-use
257< #TODO: I (Conan) copied this pylint code from modules.events
258< #Someone should check and make sure its necessary. Idk what
259< #it actually does.
260<
261< """
262< Comments class for events
263< """
264< from datetime import datetime
265< from typing import Optional, List
266< from uuid import uuid4
267< from pydantic import BaseModel, Field, validator
268< from models.commons import UserId, EventId, CommentId, Location
269< import utils
270<
271<
272<
273< class CommentRegistration(BaseModel):
274< poster_id : UserId
275< comment_text : Optional[str]
276< img_url : Optional[str]
277<
278<
279< class Comment(BaseModel):
280< id: CommentId = Field(str(uuid4()), alias='_id')
281< timestamp: str = str(datetime.now())
282< liking_users: List[UserId] = []
283---
284> # pylint: disable=E1136; see https://github.com/PyCQA/pylint/issues/3882
285> # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
286> # Pydantic specific naming for the next couple of linter disables
287> # pylint: disable=no-self-argument
288> # pylint: disable=no-self-use
289> #TODO: I (Conan) copied this pylint code from modules.events
290> #Someone should check and make sure its necessary. Idk what
291> #it actually does.
292>
293> """
294> Comments class for events
295> """
296> from datetime import datetime
297> from typing import Optional, List
298> from uuid import uuid4
299> from pydantic import BaseModel, Field, validator
300> from models.commons import UserId, EventId, CommentId, Location
301> import utils
302>
303>
304>
305> class CommentRegistration(BaseModel):
306> poster_id : UserId
307> comment_text : Optional[str]
308> img_url : Optional[str]
309>
310>
311> class Comment(BaseModel):
312> id: CommentId = Field(str(uuid4()), alias='_id')
313> timestamp: str = str(datetime.now())
314> liking_users: List[UserId] = []
315diff -r COPY/models/commons.py cardway_backend/models/commons.py
3168d7
317< from datetime import datetime
31816d14
319< CommentId = str
32065,68d62
321<
322< class EventRejection(BaseModel):
323< rejected_event_id: EventId
324< timestamp: datetime
325diff -r COPY/models/events.py cardway_backend/models/events.py
32640d39
327< LOCATION = "Location"
32889d87
329<
330diff -r COPY/models/graphql/business.py cardway_backend/models/graphql/business.py
3311,75c1,75
332< """
333< GraphQL Models for businesses
334< """
335< import graphene
336< import models.business as business_models
337< import utils.business as business_utils
338< from models.graphql import commons
339<
340<
341< class Business(commons.UserAccount):
342< _id = commons.UserId
343< business_name = graphene.String()
344< business_tag = graphene.String()
345< tagline = graphene.String()
346< description = graphene.String()
347< website_url = graphene.String()
348< hours_of_operation = graphene.String()
349< delivery_link = graphene.String()
350< location = commons.Location
351<
352<
353< class Query(graphene.ObjectType):
354< business_by_id = graphene.Field(Business,
355< business_id=graphene.ID(required=True))
356<
357< async def resolve_business_by_id(self, _, business_id):
358< business = await business_utils.get_business_by_id(business_id)
359<
360< # more explicit typecasting to deal with the funny id attribute
361< business_dict = business.dict()
362< business_dict["_id"] = business_dict["id"]
363< del business_dict["id"]
364<
365< return Business(**business_dict)
366<
367<
368< class BusinessRegistrationFormInputType(graphene.InputObjectType):
369< business_name = graphene.String()
370< business_tag = graphene.String()
371< tagline = graphene.String()
372< description = graphene.String()
373< website_url = graphene.String()
374< hours_of_operation = graphene.String()
375< delivery_link = graphene.String()
376< username = graphene.String()
377< password = graphene.String()
378< email = graphene.String()
379< phone_number = graphene.String()
380< street_address = graphene.String()
381< city = graphene.String()
382< state = graphene.String()
383< country = graphene.String()
384< zip_code = graphene.String()
385<
386<
387< class CreateBusiness(graphene.Mutation):
388< class Arguments:
389< business = graphene.Argument(BusinessRegistrationFormInputType)
390<
391< transaction_ok = graphene.Boolean()
392< business = graphene.Field(Business)
393<
394< async def mutate(self, _, business):
395< business = business_models.BusinessRegistrationForm(**business)
396< business_id = await business_utils.register_business(business)
397<
398< # explicit cast from `businessRegistration` to
399< # `business` here to set the id
400< business = Business(**business.dict(), _id=business_id)
401<
402< return CreateBusiness(transaction_ok=True, business=business)
403<
404<
405< class Mutation(graphene.ObjectType):
406< create_business = CreateBusiness.Field()
407---
408> """
409> GraphQL Models for businesses
410> """
411> import graphene
412> import models.business as business_models
413> import utils.business as business_utils
414> from models.graphql import commons
415>
416>
417> class Business(commons.UserAccount):
418> _id = commons.UserId
419> business_name = graphene.String()
420> business_tag = graphene.String()
421> tagline = graphene.String()
422> description = graphene.String()
423> website_url = graphene.String()
424> hours_of_operation = graphene.String()
425> delivery_link = graphene.String()
426> location = commons.Location
427>
428>
429> class Query(graphene.ObjectType):
430> business_by_id = graphene.Field(Business,
431> business_id=graphene.ID(required=True))
432>
433> async def resolve_business_by_id(self, _, business_id):
434> business = await business_utils.get_business_by_id(business_id)
435>
436> # more explicit typecasting to deal with the funny id attribute
437> business_dict = business.dict()
438> business_dict["_id"] = business_dict["id"]
439> del business_dict["id"]
440>
441> return Business(**business_dict)
442>
443>
444> class BusinessRegistrationFormInputType(graphene.InputObjectType):
445> business_name = graphene.String()
446> business_tag = graphene.String()
447> tagline = graphene.String()
448> description = graphene.String()
449> website_url = graphene.String()
450> hours_of_operation = graphene.String()
451> delivery_link = graphene.String()
452> username = graphene.String()
453> password = graphene.String()
454> email = graphene.String()
455> phone_number = graphene.String()
456> street_address = graphene.String()
457> city = graphene.String()
458> state = graphene.String()
459> country = graphene.String()
460> zip_code = graphene.String()
461>
462>
463> class CreateBusiness(graphene.Mutation):
464> class Arguments:
465> business = graphene.Argument(BusinessRegistrationFormInputType)
466>
467> transaction_ok = graphene.Boolean()
468> business = graphene.Field(Business)
469>
470> async def mutate(self, _, business):
471> business = business_models.BusinessRegistrationForm(**business)
472> business_id = await business_utils.register_business(business)
473>
474> # explicit cast from `businessRegistration` to
475> # `business` here to set the id
476> business = Business(**business.dict(), _id=business_id)
477>
478> return CreateBusiness(transaction_ok=True, business=business)
479>
480>
481> class Mutation(graphene.ObjectType):
482> create_business = CreateBusiness.Field()
483diff -r COPY/models/graphql/commons.py cardway_backend/models/graphql/commons.py
4841,43c1,43
485< # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
486< """
487< Project-wide commons models class.
488<
489< Includes parent object for inheritance, as well as type aliases
490< for the unique UUIDs just for some extra type safety.
491< """
492< import graphene
493<
494< EventId = graphene.ID()
495< UserId = graphene.ID()
496< PostId = graphene.ID()
497<
498<
499< class Location(graphene.ObjectType):
500< lat = graphene.Float()
501< lng = graphene.Float()
502<
503<
504< class LocationInputType(graphene.InputObjectType):
505< lat = graphene.Float()
506< lng = graphene.Float()
507<
508<
509< GrapheneEventId = graphene.ID
510< GrapheneUserId = graphene.ID
511< GraphenePostId = graphene.ID
512<
513<
514< class UserAccount(graphene.ObjectType):
515< _id = UserId
516< username = graphene.String()
517< password = graphene.String()
518< email = graphene.String()
519< phone_number = graphene.String()
520< street_address = graphene.String()
521< city = graphene.String()
522< state = graphene.String()
523< country = graphene.String()
524< zip_code = graphene.String()
525< follower_ids = graphene.List(GrapheneUserId)
526< following_ids = graphene.List(GrapheneUserId)
527< created_event_ids = graphene.List(GrapheneEventId)
528---
529> # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
530> """
531> Project-wide commons models class.
532>
533> Includes parent object for inheritance, as well as type aliases
534> for the unique UUIDs just for some extra type safety.
535> """
536> import graphene
537>
538> EventId = graphene.ID()
539> UserId = graphene.ID()
540> PostId = graphene.ID()
541>
542>
543> class Location(graphene.ObjectType):
544> lat = graphene.Float()
545> lng = graphene.Float()
546>
547>
548> class LocationInputType(graphene.InputObjectType):
549> lat = graphene.Float()
550> lng = graphene.Float()
551>
552>
553> GrapheneEventId = graphene.ID
554> GrapheneUserId = graphene.ID
555> GraphenePostId = graphene.ID
556>
557>
558> class UserAccount(graphene.ObjectType):
559> _id = UserId
560> username = graphene.String()
561> password = graphene.String()
562> email = graphene.String()
563> phone_number = graphene.String()
564> street_address = graphene.String()
565> city = graphene.String()
566> state = graphene.String()
567> country = graphene.String()
568> zip_code = graphene.String()
569> follower_ids = graphene.List(GrapheneUserId)
570> following_ids = graphene.List(GrapheneUserId)
571> created_event_ids = graphene.List(GrapheneEventId)
572diff -r COPY/models/graphql/events.py cardway_backend/models/graphql/events.py
5731,42c1,42
574< """
575< GraphQL Models for Events
576< """
577< import graphene
578< import models.events as event_models
579< import utils.events as event_utils
580< from .commons import UserId, EventId, Location
581<
582< EventPrivacy = graphene.Enum.from_enum(event_models.EventPrivacy)
583< EventTag = graphene.Enum.from_enum(event_models.EventTag)
584< StatusEnum = graphene.Enum.from_enum(event_models.StatusEnum)
585<
586<
587< class Event(graphene.ObjectType):
588< id = EventId # pylint: disable=invalid-name
589< host_id = UserId
590< name = graphene.String()
591< description = graphene.String()
592< start_time = graphene.DateTime()
593< end_time = graphene.DateTime()
594< location_name = graphene.String()
595< privacy_setting = EventPrivacy()
596< tag = EventTag()
597< location_coords = graphene.Field(Location)
598< location_name = graphene.String()
599< company_name = graphene.String()
600< status = StatusEnum()
601< hidden = graphene.Boolean()
602< timestamp = graphene.DateTime()
603< interested_users = graphene.List(graphene.ID)
604< invited_users = graphene.List(graphene.ID)
605< going_users = graphene.List(graphene.ID)
606<
607<
608< class Query(graphene.ObjectType):
609< event_by_id = graphene.Field(Event, event_id=graphene.ID(required=True))
610<
611< async def resolve_event_by_id(self, _, event_id):
612< event = await event_utils.get_event_by_id(event_id)
613<
614< # more explicit typecasting to deal with the funny id attribute
615< return Event(**event.dict())
616---
617> """
618> GraphQL Models for Events
619> """
620> import graphene
621> import models.events as event_models
622> import utils.events as event_utils
623> from .commons import UserId, EventId, Location
624>
625> EventPrivacy = graphene.Enum.from_enum(event_models.EventPrivacy)
626> EventTag = graphene.Enum.from_enum(event_models.EventTag)
627> StatusEnum = graphene.Enum.from_enum(event_models.StatusEnum)
628>
629>
630> class Event(graphene.ObjectType):
631> id = EventId # pylint: disable=invalid-name
632> host_id = UserId
633> name = graphene.String()
634> description = graphene.String()
635> start_time = graphene.DateTime()
636> end_time = graphene.DateTime()
637> location_name = graphene.String()
638> privacy_setting = EventPrivacy()
639> tag = EventTag()
640> location_coords = graphene.Field(Location)
641> location_name = graphene.String()
642> company_name = graphene.String()
643> status = StatusEnum()
644> hidden = graphene.Boolean()
645> timestamp = graphene.DateTime()
646> interested_users = graphene.List(graphene.ID)
647> invited_users = graphene.List(graphene.ID)
648> going_users = graphene.List(graphene.ID)
649>
650>
651> class Query(graphene.ObjectType):
652> event_by_id = graphene.Field(Event, event_id=graphene.ID(required=True))
653>
654> async def resolve_event_by_id(self, _, event_id):
655> event = await event_utils.get_event_by_id(event_id)
656>
657> # more explicit typecasting to deal with the funny id attribute
658> return Event(**event.dict())
659diff -r COPY/models/posts.py cardway_backend/models/posts.py
6601,30c1,30
661< """
662< Holds all of the modles for the post system.
663<
664< (Mostly defunct now but will eventually be needed)
665< """
666< from datetime import datetime
667< from enum import Enum
668< from models.commons import UserId, Location, PostId
669<
670<
671< class Privacy(Enum):
672< PUBLIC = 1
673< FOLLOWERS_ONLY = 2
674< PRIVATE = 3
675<
676<
677< # TODO: figure out what this enum is supposed to be
678< class PostType(Enum):
679< pass
680<
681<
682< class Post:
683< _id: PostId
684< poster_id: UserId
685< text: str
686< privacy_setting: Privacy
687< post_type: PostType
688< post_location: Location
689< img_url: str
690< timestamp: datetime
691---
692> """
693> Holds all of the modles for the post system.
694>
695> (Mostly defunct now but will eventually be needed)
696> """
697> from datetime import datetime
698> from enum import Enum
699> from models.commons import UserId, Location, PostId
700>
701>
702> class Privacy(Enum):
703> PUBLIC = 1
704> FOLLOWERS_ONLY = 2
705> PRIVATE = 3
706>
707>
708> # TODO: figure out what this enum is supposed to be
709> class PostType(Enum):
710> pass
711>
712>
713> class Post:
714> _id: PostId
715> poster_id: UserId
716> text: str
717> privacy_setting: Privacy
718> post_type: PostType
719> post_location: Location
720> img_url: str
721> timestamp: datetime
722diff -r COPY/models/users.py cardway_backend/models/users.py
72312d11
724<
72526,27c25
726< rejected_events: List[EventId] = []
727< rejected_locations: List[EventRejection] = []
728---
729>
730diff -r COPY/prod.sh cardway_backend/prod.sh
7311,2c1,2
732< pip3 install -r requirements.txt
733< gunicorn -w 4 -k uvicorn.workers.UvicornWorker app:app --bind 0.0.0.0:$PORT --access-logfile - --log-level info
734---
735> pip3 install -r requirements.txt
736> gunicorn -w 4 -k uvicorn.workers.UvicornWorker app:app --bind 0.0.0.0:$PORT --access-logfile - --log-level info
737diff -r COPY/runtime.txt cardway_backend/runtime.txt
7381c1
739< python-3.9.1
740---
741> python-3.9.1
742diff -r COPY/tests/conftest.py cardway_backend/tests/conftest.py
7431,31c1,31
744< """
745< Configuration for pytest suite.
746<
747< Holds teardown/runaround hooks as well as any other random
748< plugins or fixtures.
749< """
750< import os
751< import asyncio
752< import logging
753< import pytest
754< from database import main as db
755<
756<
757< def pytest_configure(config): # pylint: disable=unused-argument
758< os.environ["_called_from_test"] = "True"
759< db.connect_to_mongo()
760< logging.getLogger("faker").setLevel(logging.ERROR)
761<
762<
763< def pytest_unconfigure(config): # pylint: disable=unused-argument
764< os.environ["_called_from_test"] = "False"
765< db.clear_test_collections()
766< db.close_connection_to_mongo()
767< loop = asyncio.get_event_loop()
768< loop.close()
769<
770<
771< @pytest.fixture(autouse=True)
772< def run_around_tests():
773< yield
774< db.clear_test_collections()
775---
776> """
777> Configuration for pytest suite.
778>
779> Holds teardown/runaround hooks as well as any other random
780> plugins or fixtures.
781> """
782> import os
783> import asyncio
784> import logging
785> import pytest
786> from database import main as db
787>
788>
789> def pytest_configure(config): # pylint: disable=unused-argument
790> os.environ["_called_from_test"] = "True"
791> db.connect_to_mongo()
792> logging.getLogger("faker").setLevel(logging.ERROR)
793>
794>
795> def pytest_unconfigure(config): # pylint: disable=unused-argument
796> os.environ["_called_from_test"] = "False"
797> db.clear_test_collections()
798> db.close_connection_to_mongo()
799> loop = asyncio.get_event_loop()
800> loop.close()
801>
802>
803> @pytest.fixture(autouse=True)
804> def run_around_tests():
805> yield
806> db.clear_test_collections()
807diff -r COPY/tests/events/conftest.py cardway_backend/tests/events/conftest.py
8081,75c1,75
809< """
810< Configuration for pytest suite.
811<
812< Holds fixtures specific to events unit tests.
813< Any code that needs to be more scoped than module should not go here.
814< """
815< import datetime
816< from typing import Tuple
817< import uuid
818< from asgiref.sync import async_to_sync
819< import pytest
820< import faker
821< import utils
822< import models
823<
824<
825< @pytest.fixture(scope="function")
826< def registered_event() -> models.events.Event:
827< event_reg_form = generate_valid_event_reg_form()
828< async_to_sync(utils.events.register_event)(event_reg_form)
829< event = async_to_sync(
830< utils.events.event_from_event_registration_form)(event_reg_form)
831< return event
832<
833<
834< @pytest.fixture(scope="function")
835< def event_registration_form() -> models.events.EventRegistration:
836< return generate_valid_event_reg_form()
837<
838<
839< @pytest.fixture(scope="function")
840< def uuid4_str() -> str:
841< return str(uuid.uuid4())
842<
843<
844< @pytest.fixture(scope="function")
845< def event_model() -> models.events.Event:
846< registration_form = generate_valid_event_reg_form()
847< event = async_to_sync(
848< utils.events.event_from_event_registration_form)(registration_form)
849< return event
850<
851<
852< def generate_valid_event_reg_form() -> models.events.EventRegistration:
853< fake = faker.Faker()
854< fake_lat, fake_long = get_fake_coord_pair()
855< event_registration_data_dict = {
856< "host_id": fake.uuid4(),
857< "name": ''.join(fake.words(3)),
858< "description": fake.text(),
859< "start_time": get_datetime(),
860< "end_time": get_datetime(),
861< "privacy_setting": models.events.EventPrivacy.PUBLIC,
862< "tag": models.events.EventTag.FOOD,
863< "location_coords": {
864< "lat": fake_lat,
865< "lng": fake_long,
866< },
867< "company_name": fake.company(),
868< "location_name": fake.address(),
869< "hidden": False
870< }
871< return models.events.EventRegistration(**event_registration_data_dict)
872<
873<
874< def get_datetime() -> datetime:
875< return datetime.datetime.now()
876<
877<
878< def get_fake_coord_pair() -> Tuple[float, float]:
879< fake = faker.Faker()
880< fake_location = fake.latlng()
881< fake_lat = float(fake_location[0])
882< fake_long = float(fake_location[1])
883< return (fake_lat, fake_long)
884---
885> """
886> Configuration for pytest suite.
887>
888> Holds fixtures specific to events unit tests.
889> Any code that needs to be more scoped than module should not go here.
890> """
891> import datetime
892> from typing import Tuple
893> import uuid
894> from asgiref.sync import async_to_sync
895> import pytest
896> import faker
897> import utils
898> import models
899>
900>
901> @pytest.fixture(scope="function")
902> def registered_event() -> models.events.Event:
903> event_reg_form = generate_valid_event_reg_form()
904> async_to_sync(utils.events.register_event)(event_reg_form)
905> event = async_to_sync(
906> utils.events.event_from_event_registration_form)(event_reg_form)
907> return event
908>
909>
910> @pytest.fixture(scope="function")
911> def event_registration_form() -> models.events.EventRegistration:
912> return generate_valid_event_reg_form()
913>
914>
915> @pytest.fixture(scope="function")
916> def uuid4_str() -> str:
917> return str(uuid.uuid4())
918>
919>
920> @pytest.fixture(scope="function")
921> def event_model() -> models.events.Event:
922> registration_form = generate_valid_event_reg_form()
923> event = async_to_sync(
924> utils.events.event_from_event_registration_form)(registration_form)
925> return event
926>
927>
928> def generate_valid_event_reg_form() -> models.events.EventRegistration:
929> fake = faker.Faker()
930> fake_lat, fake_long = get_fake_coord_pair()
931> event_registration_data_dict = {
932> "host_id": fake.uuid4(),
933> "name": ''.join(fake.words(3)),
934> "description": fake.text(),
935> "start_time": get_datetime(),
936> "end_time": get_datetime(),
937> "privacy_setting": models.events.EventPrivacy.PUBLIC,
938> "tag": models.events.EventTag.FOOD,
939> "location_coords": {
940> "lat": fake_lat,
941> "lng": fake_long,
942> },
943> "company_name": fake.company(),
944> "location_name": fake.address(),
945> "hidden": False
946> }
947> return models.events.EventRegistration(**event_registration_data_dict)
948>
949>
950> def get_datetime() -> datetime:
951> return datetime.datetime.now()
952>
953>
954> def get_fake_coord_pair() -> Tuple[float, float]:
955> fake = faker.Faker()
956> fake_location = fake.latlng()
957> fake_lat = float(fake_location[0])
958> fake_long = float(fake_location[1])
959> return (fake_lat, fake_long)
960diff -r COPY/tests/events/test_events.py cardway_backend/tests/events/test_events.py
9611,287c1,287
962< # Linter disables (and explanations)
963< # pylint: disable=no-self-use
964< # pytest needs to pass in self when using class
965< # tests, regardless of actual self usage.
966< # pylint: disable=logging-fstring-interpolation
967< # Honestly just annoying to use lazy(%) interpolation.
968< """
969< Holds unit tests for event operations
970< """
971< import logging
972< import pytest
973< from starlette.exceptions import HTTPException
974< import pydantic
975< from pydantic.error_wrappers import ValidationError
976< import utils.events as event_utils
977< import models.events as event_models
978< import models.commons as common_models
979<
980<
981< # Util functions
982< def get_id_from_event(event: event_models.Event) -> common_models.EventId:
983< """
984< Stupidly small function but since ID's have been a nightmare in the past,
985< this should give us some room if/when something goes haywire again.
986< """
987< return event.id
988<
989<
990< def valid_register_event_response(event_response) -> bool:
991< """
992< As of now does a very small stupid check, but if we want to change what
993< constitutes a "valid" registration response this will come in handy.
994< """
995< return isinstance(event_response, str)
996<
997<
998< def check_event_model_objects_match(event_a: event_models.Event,
999< event_b: event_models.Event) -> bool:
1000< """
1001< Breaks the user objects into dicts then iterates over their keys and
1002< values and checks them all. Returns true if they all match, else false.
1003< """
1004< event_a_dict = event_a.dict()
1005< event_b_dict = event_b.dict()
1006<
1007< event_keys = zip(event_a_dict.keys(), event_b_dict.keys())
1008<
1009< try:
1010< for event_a_key, event_b_key in event_keys:
1011< assert event_a_key == event_b_key
1012<
1013< event_a_val = event_a_dict[event_a_key]
1014< event_b_val = event_b_dict[event_b_key]
1015< assert event_a_val == event_b_val
1016<
1017< except AssertionError as e: # pylint: disable=invalid-name
1018< logging.debug(F"assertion error in compare event objects: {e}")
1019< return False
1020< return True
1021<
1022<
1023< def make_event_reg_form_invalid(
1024< event_form: event_models.EventRegistration
1025< ) -> event_models.EventRegistration:
1026< """
1027< Given an event registration form, returns another but with all of the
1028< data shifted down by one in the attribute list, effectively breaking the
1029< validation and returning an invalid object.
1030< """
1031< event_dict = event_form.dict()
1032< event_values = (x for x in list(event_dict.values())[::-1])
1033<
1034< for key, value in zip(event_dict.keys(), event_values):
1035< event_dict[key] = value
1036<
1037< # using `model.construct()` here to bypass validation (on purpose!)
1038< event = event_models.EventRegistration.construct(**event_dict)
1039< return event
1040<
1041<
1042< def check_event_object_valid(event: event_models.Event) -> bool:
1043< """
1044< Checks if a event object is "valid". Meaning it can pass a validator and
1045< is of the correct type and instance.
1046< """
1047< try:
1048< assert isinstance(event, event_models.Event)
1049< assert is_model_cast_valid(event, event_models.Event)
1050< return True
1051< except AssertionError as e: # pylint: disable=invalid-name
1052< logging.warning(f"Event object invalid: {e}")
1053< return False
1054<
1055<
1056< def check_event_matches_reg_form(
1057< event_registration_form: event_models.EventRegistration,
1058< event: event_models.Event) -> bool:
1059< """
1060< Iterates through the event keys and finds matching
1061< keys in the event_registration dict and asserts their
1062< equality, returning false at the first mismatch.
1063< """
1064< event_reg_dict = event_registration_form.dict()
1065< event_dict = event.dict()
1066<
1067< event_reg_keys = set(event_reg_dict.keys())
1068< event_keys = event_dict.keys()
1069<
1070< try:
1071< for key in event_keys:
1072< if key in event_reg_keys:
1073< assert event_dict[key] == event_reg_dict[key]
1074< except AssertionError as e: # pylint: disable=invalid-name
1075< logging.warning(f"Event differs from event reg: {e}")
1076< return False
1077< return True
1078<
1079<
1080< def is_model_cast_valid(data_to_be_cast: pydantic.BaseModel,
1081< model_type: pydantic.BaseModel) -> bool:
1082< """
1083< Tries to cast the date to be cast into the model type and returns true
1084< if succesful, else returns false.
1085< """
1086< try:
1087< model_type(**data_to_be_cast.dict())
1088< return True
1089< except ValidationError:
1090< return False
1091<
1092<
1093< class TestEventUtilsUnit:
1094< class TestGetEventByID:
1095< class TestSunnyDayCases:
1096< """
1097< Holds test cases that should _always_ pass.
1098< A failing test here means something broke and should be
1099< fixed with high priority.
1100< """
1101< @pytest.mark.asyncio
1102< async def test_get_existing_event_by_id(
1103< self, registered_event: event_models.Event):
1104< """
1105< Tests a succesful query from the database of a valid registered
1106< event by ID.
1107< """
1108< event_id = get_id_from_event(registered_event)
1109< event = await event_utils.get_event_by_id(event_id)
1110< assert check_event_matches_reg_form(event, registered_event)
1111<
1112< class TestRainyDayCases:
1113< """
1114< These test cases always expect failure.
1115< If they pass, it means something has gone very very
1116< wrong with the validation layer of the app.
1117< """
1118< @pytest.mark.asyncio
1119< async def test_get_nonexistent_event(self, uuid4_str):
1120< """
1121< Tests a query with a valid ID but without ever registering it.
1122< Should always fail and return a 404.
1123< """
1124< try:
1125< await event_utils.get_event_by_id(uuid4_str)
1126< assert False
1127< except HTTPException as e: # pylint: disable=invalid-name
1128< assert e.status_code == 404
1129<
1130< @pytest.mark.asyncio
1131< async def test_get_invalid_id_type(self, registered_event):
1132< """
1133< Tests a query for a valid and existing event but the ID type
1134< is not str(uuid4). Expects a 422 failure.
1135< """
1136< del registered_event # unused var
1137< invalid_id = 422
1138< try:
1139< await event_utils.get_event_by_id(invalid_id)
1140< assert False
1141< except HTTPException as e: # pylint: disable=invalid-name
1142< assert e.status_code == 422
1143<
1144< class TestRegisterEvent:
1145< class TestSunnyDayCases:
1146< @pytest.mark.asyncio
1147< async def test_get_existing_event_by_id(
1148< self,
1149< event_registration_form: event_models.EventRegistration):
1150< """
1151< Tests succesful event registration from an
1152< event registration form.
1153< """
1154< event_id = await event_utils.register_event(
1155< event_registration_form)
1156< assert valid_register_event_response(event_id)
1157<
1158< class TestRainyDayCases:
1159< @pytest.mark.asyncio
1160< async def test_invalid_event_data(
1161< self,
1162< event_registration_form: event_models.EventRegistration):
1163< """
1164< Tests the response of not trying to register an event
1165< with invalid data. Should fail with a 422 always.
1166< """
1167< invalid_event = make_event_reg_form_invalid(
1168< event_registration_form)
1169< try:
1170< await event_utils.register_event(invalid_event)
1171< assert False
1172< except HTTPException as e: # pylint: disable=invalid-name
1173< assert e.status_code == 422
1174<
1175< @pytest.mark.asyncio
1176< async def test_invalid_data_type(self):
1177< """
1178< Tests the response of not trying to register an event
1179< with invalid data. Should fail with a 422 always.
1180< """
1181< invalid_event_form = 22 # this is a dumb example but it works.
1182< try:
1183< await event_utils.register_event(invalid_event_form)
1184< assert False
1185< except HTTPException as e: # pylint: disable=invalid-name
1186< assert e.status_code == 422
1187<
1188< class TestCheckEventExists:
1189< class TestSunnyDayCases:
1190< @pytest.mark.asyncio
1191< async def test_check_existing_event(
1192< self, registered_event: event_models.Event):
1193< """
1194< Tests that an event exists when it has been registered.
1195< """
1196< event_id = get_id_from_event(registered_event)
1197< event_exists = await event_utils.check_event_exists(event_id)
1198< assert event_exists
1199<
1200< class TestRainyDayCases:
1201< @pytest.mark.asyncio
1202< async def test_invalid_event_id_type_fail(
1203< self, registered_event: event_models.Event):
1204< """
1205< Tries to check if an event exists with an invalid data
1206< type for the EventId parameter.
1207< """
1208< del registered_event # unused var
1209< invalid_event_id = "invaliduuid"
1210< try:
1211< await event_utils.check_event_exists(invalid_event_id)
1212< assert False
1213< except HTTPException as e: # pylint: disable=invalid-name
1214< assert e.status_code == 422
1215<
1216< class TestEventFromEventRegistration:
1217< class TestSunnyDayCases:
1218< @pytest.mark.asyncio
1219< async def test_valid_event_reg_to_event(
1220< self,
1221< event_registration_form: event_models.EventRegistration):
1222< """
1223< Passes in a valid event registration form and expects a valid
1224< event object in return.
1225< """
1226< event = await event_utils.event_from_event_registration_form(
1227< event_registration_form)
1228< assert check_event_object_valid(event)
1229< assert check_event_matches_reg_form(event_registration_form,
1230< event)
1231<
1232< class TestRainyDayCases:
1233< @pytest.mark.asyncio
1234< async def test_invalid_event_failure(
1235< self,
1236< event_registration_form: event_models.EventRegistration):
1237< """
1238< Creates an invalid event registration form and expects the
1239< validator to throw an error.
1240< """
1241< invalid_event_form = make_event_reg_form_invalid(
1242< event_registration_form)
1243< try:
1244< await event_utils.event_from_event_registration_form(
1245< invalid_event_form)
1246< assert False
1247< except HTTPException as e: # pylint: disable=invalid-name
1248< assert e.status_code == 422
1249---
1250> # Linter disables (and explanations)
1251> # pylint: disable=no-self-use
1252> # pytest needs to pass in self when using class
1253> # tests, regardless of actual self usage.
1254> # pylint: disable=logging-fstring-interpolation
1255> # Honestly just annoying to use lazy(%) interpolation.
1256> """
1257> Holds unit tests for event operations
1258> """
1259> import logging
1260> import pytest
1261> from starlette.exceptions import HTTPException
1262> import pydantic
1263> from pydantic.error_wrappers import ValidationError
1264> import utils.events as event_utils
1265> import models.events as event_models
1266> import models.commons as common_models
1267>
1268>
1269> # Util functions
1270> def get_id_from_event(event: event_models.Event) -> common_models.EventId:
1271> """
1272> Stupidly small function but since ID's have been a nightmare in the past,
1273> this should give us some room if/when something goes haywire again.
1274> """
1275> return event.id
1276>
1277>
1278> def valid_register_event_response(event_response) -> bool:
1279> """
1280> As of now does a very small stupid check, but if we want to change what
1281> constitutes a "valid" registration response this will come in handy.
1282> """
1283> return isinstance(event_response, str)
1284>
1285>
1286> def check_event_model_objects_match(event_a: event_models.Event,
1287> event_b: event_models.Event) -> bool:
1288> """
1289> Breaks the user objects into dicts then iterates over their keys and
1290> values and checks them all. Returns true if they all match, else false.
1291> """
1292> event_a_dict = event_a.dict()
1293> event_b_dict = event_b.dict()
1294>
1295> event_keys = zip(event_a_dict.keys(), event_b_dict.keys())
1296>
1297> try:
1298> for event_a_key, event_b_key in event_keys:
1299> assert event_a_key == event_b_key
1300>
1301> event_a_val = event_a_dict[event_a_key]
1302> event_b_val = event_b_dict[event_b_key]
1303> assert event_a_val == event_b_val
1304>
1305> except AssertionError as e: # pylint: disable=invalid-name
1306> logging.debug(F"assertion error in compare event objects: {e}")
1307> return False
1308> return True
1309>
1310>
1311> def make_event_reg_form_invalid(
1312> event_form: event_models.EventRegistration
1313> ) -> event_models.EventRegistration:
1314> """
1315> Given an event registration form, returns another but with all of the
1316> data shifted down by one in the attribute list, effectively breaking the
1317> validation and returning an invalid object.
1318> """
1319> event_dict = event_form.dict()
1320> event_values = (x for x in list(event_dict.values())[::-1])
1321>
1322> for key, value in zip(event_dict.keys(), event_values):
1323> event_dict[key] = value
1324>
1325> # using `model.construct()` here to bypass validation (on purpose!)
1326> event = event_models.EventRegistration.construct(**event_dict)
1327> return event
1328>
1329>
1330> def check_event_object_valid(event: event_models.Event) -> bool:
1331> """
1332> Checks if a event object is "valid". Meaning it can pass a validator and
1333> is of the correct type and instance.
1334> """
1335> try:
1336> assert isinstance(event, event_models.Event)
1337> assert is_model_cast_valid(event, event_models.Event)
1338> return True
1339> except AssertionError as e: # pylint: disable=invalid-name
1340> logging.warning(f"Event object invalid: {e}")
1341> return False
1342>
1343>
1344> def check_event_matches_reg_form(
1345> event_registration_form: event_models.EventRegistration,
1346> event: event_models.Event) -> bool:
1347> """
1348> Iterates through the event keys and finds matching
1349> keys in the event_registration dict and asserts their
1350> equality, returning false at the first mismatch.
1351> """
1352> event_reg_dict = event_registration_form.dict()
1353> event_dict = event.dict()
1354>
1355> event_reg_keys = set(event_reg_dict.keys())
1356> event_keys = event_dict.keys()
1357>
1358> try:
1359> for key in event_keys:
1360> if key in event_reg_keys:
1361> assert event_dict[key] == event_reg_dict[key]
1362> except AssertionError as e: # pylint: disable=invalid-name
1363> logging.warning(f"Event differs from event reg: {e}")
1364> return False
1365> return True
1366>
1367>
1368> def is_model_cast_valid(data_to_be_cast: pydantic.BaseModel,
1369> model_type: pydantic.BaseModel) -> bool:
1370> """
1371> Tries to cast the date to be cast into the model type and returns true
1372> if succesful, else returns false.
1373> """
1374> try:
1375> model_type(**data_to_be_cast.dict())
1376> return True
1377> except ValidationError:
1378> return False
1379>
1380>
1381> class TestEventUtilsUnit:
1382> class TestGetEventByID:
1383> class TestSunnyDayCases:
1384> """
1385> Holds test cases that should _always_ pass.
1386> A failing test here means something broke and should be
1387> fixed with high priority.
1388> """
1389> @pytest.mark.asyncio
1390> async def test_get_existing_event_by_id(
1391> self, registered_event: event_models.Event):
1392> """
1393> Tests a succesful query from the database of a valid registered
1394> event by ID.
1395> """
1396> event_id = get_id_from_event(registered_event)
1397> event = await event_utils.get_event_by_id(event_id)
1398> assert check_event_matches_reg_form(event, registered_event)
1399>
1400> class TestRainyDayCases:
1401> """
1402> These test cases always expect failure.
1403> If they pass, it means something has gone very very
1404> wrong with the validation layer of the app.
1405> """
1406> @pytest.mark.asyncio
1407> async def test_get_nonexistent_event(self, uuid4_str):
1408> """
1409> Tests a query with a valid ID but without ever registering it.
1410> Should always fail and return a 404.
1411> """
1412> try:
1413> await event_utils.get_event_by_id(uuid4_str)
1414> assert False
1415> except HTTPException as e: # pylint: disable=invalid-name
1416> assert e.status_code == 404
1417>
1418> @pytest.mark.asyncio
1419> async def test_get_invalid_id_type(self, registered_event):
1420> """
1421> Tests a query for a valid and existing event but the ID type
1422> is not str(uuid4). Expects a 422 failure.
1423> """
1424> del registered_event # unused var
1425> invalid_id = 422
1426> try:
1427> await event_utils.get_event_by_id(invalid_id)
1428> assert False
1429> except HTTPException as e: # pylint: disable=invalid-name
1430> assert e.status_code == 422
1431>
1432> class TestRegisterEvent:
1433> class TestSunnyDayCases:
1434> @pytest.mark.asyncio
1435> async def test_get_existing_event_by_id(
1436> self,
1437> event_registration_form: event_models.EventRegistration):
1438> """
1439> Tests succesful event registration from an
1440> event registration form.
1441> """
1442> event_id = await event_utils.register_event(
1443> event_registration_form)
1444> assert valid_register_event_response(event_id)
1445>
1446> class TestRainyDayCases:
1447> @pytest.mark.asyncio
1448> async def test_invalid_event_data(
1449> self,
1450> event_registration_form: event_models.EventRegistration):
1451> """
1452> Tests the response of not trying to register an event
1453> with invalid data. Should fail with a 422 always.
1454> """
1455> invalid_event = make_event_reg_form_invalid(
1456> event_registration_form)
1457> try:
1458> await event_utils.register_event(invalid_event)
1459> assert False
1460> except HTTPException as e: # pylint: disable=invalid-name
1461> assert e.status_code == 422
1462>
1463> @pytest.mark.asyncio
1464> async def test_invalid_data_type(self):
1465> """
1466> Tests the response of not trying to register an event
1467> with invalid data. Should fail with a 422 always.
1468> """
1469> invalid_event_form = 22 # this is a dumb example but it works.
1470> try:
1471> await event_utils.register_event(invalid_event_form)
1472> assert False
1473> except HTTPException as e: # pylint: disable=invalid-name
1474> assert e.status_code == 422
1475>
1476> class TestCheckEventExists:
1477> class TestSunnyDayCases:
1478> @pytest.mark.asyncio
1479> async def test_check_existing_event(
1480> self, registered_event: event_models.Event):
1481> """
1482> Tests that an event exists when it has been registered.
1483> """
1484> event_id = get_id_from_event(registered_event)
1485> event_exists = await event_utils.check_event_exists(event_id)
1486> assert event_exists
1487>
1488> class TestRainyDayCases:
1489> @pytest.mark.asyncio
1490> async def test_invalid_event_id_type_fail(
1491> self, registered_event: event_models.Event):
1492> """
1493> Tries to check if an event exists with an invalid data
1494> type for the EventId parameter.
1495> """
1496> del registered_event # unused var
1497> invalid_event_id = "invaliduuid"
1498> try:
1499> await event_utils.check_event_exists(invalid_event_id)
1500> assert False
1501> except HTTPException as e: # pylint: disable=invalid-name
1502> assert e.status_code == 422
1503>
1504> class TestEventFromEventRegistration:
1505> class TestSunnyDayCases:
1506> @pytest.mark.asyncio
1507> async def test_valid_event_reg_to_event(
1508> self,
1509> event_registration_form: event_models.EventRegistration):
1510> """
1511> Passes in a valid event registration form and expects a valid
1512> event object in return.
1513> """
1514> event = await event_utils.event_from_event_registration_form(
1515> event_registration_form)
1516> assert check_event_object_valid(event)
1517> assert check_event_matches_reg_form(event_registration_form,
1518> event)
1519>
1520> class TestRainyDayCases:
1521> @pytest.mark.asyncio
1522> async def test_invalid_event_failure(
1523> self,
1524> event_registration_form: event_models.EventRegistration):
1525> """
1526> Creates an invalid event registration form and expects the
1527> validator to throw an error.
1528> """
1529> invalid_event_form = make_event_reg_form_invalid(
1530> event_registration_form)
1531> try:
1532> await event_utils.event_from_event_registration_form(
1533> invalid_event_form)
1534> assert False
1535> except HTTPException as e: # pylint: disable=invalid-name
1536> assert e.status_code == 422
1537Only in cardway_backend/tests: geo
1538diff -r COPY/tests/ignore_test_old.py cardway_backend/tests/ignore_test_old.py
15391,941c1,941
1540< # pylint: skip-file
1541< import api
1542< from models import User, Event, Post, UU_relationship, UP_relationship, UE_relationship, Function, FunCall
1543< from datetime import datetime, timedelta
1544< import unittest
1545< from exceptions import UserAlreadyExistsError
1546< import scripts
1547<
1548< num_user = 0
1549< num_event = 0
1550< num_post = 0
1551<
1552<
1553< def generate_test_user(username="TestUser",
1554< password="TestPassword",
1555< first_name="Test",
1556< last_name="User",
1557< email="TestUser@card-way.com",
1558< phone_number="123-456-7890",
1559< birthday=datetime.now(),
1560< street_address="123, Bobrey Rd.",
1561< city="Rochester",
1562< state="NY",
1563< country="USA",
1564< zipcode="12345",
1565< company=False,
1566< salt=None):
1567< global num_user
1568< sesh = api.get_session()
1569< num_user += 1
1570< if username == "TestUser":
1571< username = "TestUser" + str(num_user)
1572< return api.user_post_new(sesh, username, password, first_name, last_name,
1573< email, phone_number, birthday, street_address,
1574< city, state, country, zipcode, company, salt)
1575<
1576<
1577< def auto_make_test_event(host_id,
1578< description="Come over, have fun!",
1579< start_time=datetime.now() - timedelta(1),
1580< end_time=datetime.now() + timedelta(1),
1581< location_name="Jonny's House",
1582< privacy_setting=api.EvPrivacy.PUBLIC,
1583< tag=api.EvTags.DANCE,
1584< event_lat=1.1,
1585< event_lng=2.2,
1586< active=True,
1587< company=False,
1588< promotion=False,
1589< hide=False,
1590< invitees=[]):
1591< sesh = api.get_session()
1592< return api.user_make_event(sesh,
1593< host_id,
1594< description=description,
1595< start_time=start_time,
1596< end_time=end_time,
1597< location_name=location_name,
1598< privacy_setting=privacy_setting,
1599< tag=tag,
1600< event_lat=event_lat,
1601< event_lng=event_lng,
1602< active=active,
1603< company=company,
1604< promotion=promotion,
1605< invited_users=invitees)
1606<
1607<
1608< def refresh():
1609< sesh = api.get_session()
1610< print(sesh.query(FunCall).count())
1611< sesh.query(User).delete()
1612< sesh.query(Event).delete()
1613< sesh.query(Post).delete()
1614< sesh.query(UU_relationship).delete()
1615< sesh.query(UE_relationship).delete()
1616< sesh.query(UP_relationship).delete()
1617< sesh.query(Function).delete()
1618< sesh.query(FunCall).delete()
1619< sesh.commit()
1620<
1621<
1622< class Testing(unittest.TestCase):
1623< def test_unit_post_new(self):
1624< refresh()
1625< sesh = api.get_session()
1626< cur_time = datetime.now()
1627< test_id = api.user_post_new(sesh, "user1", "BobJones", "Bob", "Jones", "BobJones123@hotmail.com", "565-567-6789",\
1628< cur_time, "213B Baker Street", "London", "NY", "USA", "12345", False)
1629< self.assertEqual(sesh.query(User).count(), 1)
1630< #We need to [_sa_instance_state] because each dict will be created with a new one, even if everything else
1631< #(including primary keys) are the same.
1632< test_user = sesh.query(User).filter(
1633< User.id == test_id).first().__dict__
1634< usr_salt = test_user['pass_hash_salt'].split('$')[2]
1635< check_user = User(username = "user1", pass_hash_salt = "$"+ api.hash_password("BobJones",usr_salt) + "$" + usr_salt,\
1636< first_name = "Bob", last_name = "Jones", email = "BobJones123@hotmail.com", phone = "565-567-6789",\
1637< street_address = "213B Baker Street", city = "London", state = "NY", country = "USA", zipcode = "12345",\
1638< birthday = cur_time, company = False, id = test_id).__dict__
1639< test_user.pop('_sa_instance_state')
1640< check_user.pop('_sa_instance_state')
1641<
1642< # print(str(test_user))
1643< # print("*************")
1644< # print(str(check_user))
1645< self.assertTrue(test_user == check_user)
1646< self.assertRaises(UserAlreadyExistsError, api.user_post_new, sesh, "user1", "BobJones2", "Bob2", "Jones2", "BobJones123@hotmail.com2", "565-567-67892",\
1647< cur_time, "213B Baker Street2", "London2", "NY2", "USA2", "123452", False, None)
1648<
1649< def test_event_post_new(self):
1650< refresh()
1651< cur_time = datetime.now()
1652< sesh = api.get_session()
1653< end_time = cur_time + timedelta(1)
1654< start_time = cur_time - timedelta(1)
1655< test_user_id = api.user_post_new(sesh, "user1", "BobJones", "Bob", "Jones", "BobJones123@hotmail.com", "565-567-6789",\
1656< cur_time, "213B Baker Street", "London", "NY", "USA", "12345", False)
1657< test_id = api.event_post_new(sesh, test_user_id, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
1658< 1.1,2.2, True, False, False, False, False, cur_time,)
1659< self.assertEqual(sesh.query(Event).count(), 1)
1660< test_event = sesh.query(Event).filter(
1661< Event.id == test_id).first().__dict__
1662< test_event.pop('_sa_instance_state')
1663< check_event = Event(id = test_id, host = test_user_id, location_name = "Jonny's House", description = "Come over for a fun time!", start_time = start_time,\
1664< end_time = end_time, privacy_setting = api.EvPrivacy.PUBLIC.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = cur_time,
1665< active = True, company = False, promotion = False, hide = False, location = False ).__dict__
1666< check_event.pop('_sa_instance_state')
1667< self.assertEqual(test_event, check_event)
1668<
1669< def test_user_follow_user(self):
1670< refresh()
1671< sesh = api.get_session()
1672< id1 = generate_test_user()
1673< id2 = generate_test_user()
1674< self.assertFalse(api.user_check_followee_of(sesh, id1, id2))
1675< self.assertFalse(api.user_check_followee_of(sesh, id2, id1))
1676< self.assertFalse(api.user_check_follower_of(sesh, id1, id2))
1677< self.assertFalse(api.user_check_follower_of(sesh, id2, id1))
1678< api.user_follow_user(sesh, id1, id2)
1679< self.assertEquals(sesh.query(FunCall).count(), 1)
1680< self.assertFalse(api.user_check_followee_of(sesh, id1, id2))
1681< self.assertTrue(api.user_check_followee_of(sesh, id2, id1))
1682< self.assertTrue(api.user_check_follower_of(sesh, id1, id2))
1683< self.assertFalse(api.user_check_follower_of(sesh, id2, id1))
1684< api.user_follow_user(sesh, id2, id1)
1685< self.assertTrue(api.user_check_followee_of(sesh, id1, id2))
1686< self.assertTrue(api.user_check_followee_of(sesh, id2, id1))
1687< self.assertTrue(api.user_check_follower_of(sesh, id1, id2))
1688< self.assertTrue(api.user_check_follower_of(sesh, id2, id1))
1689<
1690< def test_user_mutually_following(self):
1691< refresh()
1692< sesh = api.get_session()
1693< id1 = generate_test_user()
1694< id2 = generate_test_user()
1695< self.assertFalse(api.user_mutually_following(sesh, id1, id2))
1696< api.user_follow_user(sesh, id1, id2)
1697< self.assertFalse(api.user_mutually_following(sesh, id1, id2))
1698< api.user_follow_user(sesh, id2, id1)
1699< self.assertTrue(api.user_mutually_following(sesh, id2, id1))
1700<
1701< def test_num_same_followees(self):
1702< refresh()
1703< sesh = api.get_session()
1704< n = 10
1705< count = 0
1706< u_id1 = generate_test_user()
1707< u_id2 = generate_test_user()
1708< u_id3 = generate_test_user()
1709< # api.user_follow_user(sesh, u_id1,u_id3)
1710< # api.user_follow_user(sesh, u_id2,u_id3)
1711< # self.assertEqual(api.user_num_same_followees(sesh, u_id1,u_id2), 1)
1712< # self.assertEqual(api.user_num_same_followees(sesh, u_id2,u_id3), 0)
1713< # self.assertEqual(api.user_num_same_followees(sesh, u_id3,u_id1), 0)
1714< for i in range(n):
1715< u_id = generate_test_user()
1716< if i % 2 == 0:
1717< api.user_follow_user(sesh, u_id1, u_id)
1718< if i % 3 == 0:
1719< api.user_follow_user(sesh, u_id2, u_id)
1720< if i % 6 == 0:
1721< api.user_follow_user(sesh, u_id3, u_id)
1722< count = count + 1
1723< self.assertEqual(api.user_num_same_followees(sesh, u_id1, u_id2),
1724< count)
1725< self.assertEqual(api.user_num_same_followees(sesh, u_id2, u_id3),
1726< count)
1727< self.assertEqual(api.user_num_same_followees(sesh, u_id3, u_id1),
1728< count)
1729<
1730< def test_user_post_be_invited(self):
1731< refresh()
1732< sesh = api.get_session()
1733< u_id1 = generate_test_user()
1734< u_id2 = generate_test_user()
1735< cur_time = datetime.now()
1736< end_time = cur_time + timedelta(1)
1737< start_time = cur_time - timedelta(1)
1738< e_id1 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
1739< 1.1,2.2, True, False, False, False, False, cur_time)
1740< api.user_post_be_invited(sesh, u_id2, e_id1)
1741< self.assertTrue(api.user_check_invited_to(sesh, u_id2, e_id1))
1742<
1743< def test_user_invite_to_event(self):
1744< refresh()
1745< sesh = api.get_session()
1746< #Sets up user_relationships
1747< u_id1 = generate_test_user()
1748< u_id2 = generate_test_user()
1749< u_id3 = generate_test_user()
1750< u_id4 = generate_test_user()
1751< u_id5 = generate_test_user()
1752< u_id6 = generate_test_user()
1753< api.user_follow_user(sesh, u_id4, u_id1)
1754< api.user_follow_user(sesh, u_id5, u_id1)
1755< api.user_follow_user(sesh, u_id6, u_id1)
1756< cur_time = datetime.now()
1757< end_time = cur_time + timedelta(1)
1758< start_time = cur_time - timedelta(1)
1759<
1760< #Checks what happens when privacy is PUBLIC
1761< e_id1 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
1762< 1.1,2.2, True, False, False, False, False, cur_time)
1763< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
1764< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
1765< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
1766< api.user_invite_to_event(sesh, u_id2, e_id1,
1767< u_id1) #Host cannot be invited to own event.
1768< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
1769< api.user_invite_to_event(sesh, u_id2, e_id1,
1770< u_id2) #User cannot invite self.
1771< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
1772< api.user_invite_to_event(sesh, u_id2, e_id1,
1773< u_id3) #User can invite other non-follower.
1774< self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
1775< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
1776< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
1777<
1778< #Checks what happens when privacy is FOLLOWERS_ONLY
1779< e_id2 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.FOLLOWERS_ONLY, api.EvTags.DANCE,\
1780< 1.1,2.2, True, False, False, False, False, cur_time)
1781< e_id3 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.FOLLOWERS_ONLY, api.EvTags.DANCE,\
1782< 1.1,2.2, True, False, False, False, False, cur_time)
1783< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1784< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1785< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
1786< api.user_invite_to_event(sesh, u_id2, e_id2,
1787< u_id1) #Host cannot be invited
1788< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1789< api.user_invite_to_event(sesh, u_id2, e_id2,
1790< u_id2) #User cannot invite self
1791< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1792< api.user_invite_to_event(
1793< sesh, u_id2, e_id2,
1794< u_id3) #Non-follower user cannot invite non-follower
1795< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
1796< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1797< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1798< api.user_invite_to_event(
1799< sesh, u_id2, e_id2,
1800< u_id4) #Non-user follower cannot invite follower
1801< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
1802< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
1803< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1804< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1805< api.user_invite_to_event(sesh, u_id4, e_id2,
1806< u_id3) #Follower cannot invite non-follower
1807< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
1808< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
1809< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1810< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1811< api.user_invite_to_event(sesh, u_id4, e_id2,
1812< u_id5) #Follower can invite follower
1813< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
1814< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
1815< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
1816< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
1817< self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id2))
1818< api.user_invite_to_event(sesh, u_id1, e_id3,
1819< u_id6) #Host can invite follower
1820< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id3))
1821< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id3))
1822< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id3))
1823< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id3))
1824< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id3))
1825< self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id3))
1826< api.user_invite_to_event(sesh, u_id1, e_id3,
1827< u_id3) #Host can invite non-follower
1828< self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id3))
1829< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id3))
1830< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id3))
1831<
1832< #Checks what happens when privacy is INVITATION ONLY
1833< e_id5 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.INVITATION_ONLY, api.EvTags.DANCE,\
1834< 1.1,2.2, True, False, False, False, False, cur_time)
1835< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1836< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1837< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1838< api.user_invite_to_event(sesh, u_id2, e_id5,
1839< u_id1) #Non-follower cannot invite host
1840< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1841< api.user_invite_to_event(sesh, u_id2, e_id5,
1842< u_id2) #Non-follower cannot invite follower
1843< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1844< api.user_invite_to_event(
1845< sesh, u_id2, e_id5,
1846< u_id3) #Non-follower cannot invite non-follower
1847< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1848< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1849< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1850< api.user_invite_to_event(sesh, u_id2, e_id5,
1851< u_id4) #Non-follower cannot invite follower
1852< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
1853< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1854< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1855< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1856< api.user_invite_to_event(sesh, u_id4, e_id5,
1857< u_id3) #Follower cannot invite follower
1858< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
1859< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1860< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1861< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1862< api.user_invite_to_event(sesh, u_id4, e_id5,
1863< u_id5) #Follower cannot invite follower
1864< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
1865< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1866< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1867< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1868< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
1869< api.user_invite_to_event(sesh, u_id1, e_id5,
1870< u_id6) #Host can invite follower
1871< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
1872< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1873< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1874< self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
1875< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
1876< self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id5))
1877< api.user_invite_to_event(sesh, u_id1, e_id5,
1878< u_id2) #Host can invite non-follower
1879< self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
1880< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
1881< self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
1882< self.assertTrue(api.user_check_invited_to(sesh, u_id2, e_id5))
1883< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
1884< self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id5))
1885<
1886< def test_user_make_event(self):
1887< refresh()
1888< sesh = api.get_session()
1889< #Runs the test one time for each privacy setting:
1890< for priv_setting in api.EvPrivacy:
1891< refresh()
1892< sesh = api.get_session()
1893< u_id1 = generate_test_user()
1894< u_id2 = generate_test_user()
1895< user_ids = []
1896< for i in range(10):
1897< user_ids.append(generate_test_user())
1898< if i % 2 == 0:
1899< api.user_follow_user(sesh, user_ids[i], u_id1)
1900< cur_time = datetime.now()
1901< end_time = cur_time + timedelta(1)
1902< start_time = cur_time - timedelta(1)
1903<
1904< #Checks when no users have been invited
1905< current_count = sesh.query(Event).count()
1906<
1907< ev_id = api.user_make_event(sesh, u_id1, "Come over, have fun!",
1908< start_time, end_time, "Jonny's House",
1909< priv_setting, api.EvTags.DANCE, 1.1,
1910< 2.2, True, False, False, [])
1911< self.assertEqual(sesh.query(Event).count(),
1912< current_count + 1) #Some event has been added
1913< api.check_event_exists(
1914< sesh, ev_id
1915< ) #id returned is valid event id (check_event_exists throws an error if not)
1916< new_event = sesh.query(Event).filter(
1917< Event.id == ev_id).first().__dict__
1918< new_event.pop('_sa_instance_state')
1919< check_event = Event(id = ev_id, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
1920< end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
1921< active = True, company = False, promotion = False, hide = False, location = False ).__dict__
1922< check_event.pop('_sa_instance_state')
1923<
1924< self.assertEqual(
1925< new_event,
1926< check_event) #Event with correct values has been added
1927< self.assertFalse(api.user_check_invited_to(
1928< sesh, u_id2, ev_id)) #u_id2 has not been invited
1929< for i in range(len(user_ids)): #No other users were invited
1930< self.assertFalse(
1931< api.user_check_invited_to(sesh, user_ids[i], ev_id))
1932<
1933< #Checks when one user has been invited
1934< current_count = sesh.query(Event).count()
1935<
1936< ev_id2 = api.user_make_event(sesh, u_id1, "Come over, have fun!",
1937< start_time, end_time, "Jonny's House",
1938< priv_setting, api.EvTags.DANCE, 1.1,
1939< 2.2, True, False, False, [u_id2])
1940<
1941< self.assertEqual(sesh.query(Event).count(),
1942< current_count + 1) #Some event has been added
1943< api.check_event_exists(
1944< sesh, ev_id2
1945< ) #id returned is valid event id (check_event_exists throws an error if not)
1946< new_event = sesh.query(Event).filter(
1947< Event.id == ev_id2).first().__dict__
1948< new_event.pop('_sa_instance_state')
1949< check_event = Event(id = ev_id2, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
1950< end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
1951< active = True, company = False, promotion = False, hide = False, location = False ).__dict__
1952< check_event.pop('_sa_instance_state')
1953< self.assertEqual(
1954< new_event,
1955< check_event) #Event with correct values has been added
1956< self.assertTrue(api.user_check_invited_to(
1957< sesh, u_id2, ev_id2)) #u_id2 was invited
1958< for i in range(len(user_ids)): #No other users were invited
1959< self.assertFalse(
1960< api.user_check_invited_to(sesh, user_ids[i], ev_id2))
1961<
1962< #Checks when 10 users have been invited
1963< current_count = sesh.query(Event).count()
1964<
1965< ev_id3 = api.user_make_event(sesh, u_id1, "Come over, have fun!",
1966< start_time, end_time, "Jonny's House",
1967< priv_setting, api.EvTags.DANCE, 1.1,
1968< 2.2, True, False, False, user_ids)
1969<
1970< self.assertEqual(sesh.query(Event).count(),
1971< current_count + 1) #Some event has been added
1972< api.check_event_exists(
1973< sesh, ev_id3
1974< ) #id returned is valid event id (check_event_exists throws an error if not)
1975< new_event = sesh.query(Event).filter(
1976< Event.id == ev_id3).first().__dict__
1977< new_event.pop('_sa_instance_state')
1978< check_event = Event(id = ev_id3, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
1979< end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
1980< active = True, company = False, promotion = False, hide = False, location = False ).__dict__
1981< check_event.pop('_sa_instance_state')
1982< self.assertEqual(
1983< new_event,
1984< check_event) #Event with correct values has been added
1985< self.assertFalse(api.user_check_invited_to(
1986< sesh, u_id2, ev_id3)) #u_id2 was not invited
1987< for i in range(len(user_ids)): #10 other users were invited
1988< self.assertTrue(
1989< api.user_check_invited_to(sesh, user_ids[i], ev_id3))
1990<
1991< def test_user_like_event(self):
1992< refresh()
1993< sesh = api.get_session()
1994< u_id1 = generate_test_user()
1995< u_id2 = generate_test_user()
1996< u_id3 = generate_test_user()
1997< u_id4 = generate_test_user()
1998< u_id5 = generate_test_user()
1999< api.user_follow_user(sesh, u_id4, u_id1)
2000< api.user_follow_user(sesh, u_id5, u_id1)
2001< #Checks when privacy is PUBLIC
2002< e_id1 = auto_make_test_event(u_id1,
2003< privacy_setting=api.EvPrivacy.PUBLIC,
2004< invitees=[u_id3, u_id5])
2005< api.user_like_event(sesh, u_id1, e_id1) #Host cannot like own event
2006< self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id1))
2007< api.user_like_event(sesh, u_id2,
2008< e_id1) #Non-invited non-follower can like event
2009< self.assertTrue(api.user_check_like_event(sesh, u_id2, e_id1))
2010< api.user_like_event(sesh, u_id3,
2011< e_id1) #Invited non-follower can like event
2012< self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id1))
2013< api.user_like_event(sesh, u_id4,
2014< e_id1) #Non-invited follower can like event
2015< self.assertTrue(api.user_check_like_event(sesh, u_id4, e_id1))
2016< api.user_like_event(sesh, u_id5,
2017< e_id1) #Invited follower can like event
2018< self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id1))
2019< #Checks when privacy is FOLLOWERS_ONLY
2020< e_id2 = auto_make_test_event(
2021< u_id1,
2022< privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
2023< invitees=[u_id3, u_id5])
2024< api.user_like_event(sesh, u_id1, e_id2) #Host cannot like own event
2025< self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id2))
2026< api.user_like_event(sesh, u_id2,
2027< e_id2) #Non-invited non-follower cannot like event
2028< self.assertFalse(api.user_check_like_event(sesh, u_id2, e_id2))
2029< api.user_like_event(sesh, u_id3,
2030< e_id2) #Invited non-follower can like event
2031< self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id2))
2032< api.user_like_event(sesh, u_id4,
2033< e_id2) #Non-invited follower can like event
2034< self.assertTrue(api.user_check_like_event(sesh, u_id4, e_id2))
2035< api.user_like_event(sesh, u_id5,
2036< e_id2) #Invited follower can like event
2037< self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id2))
2038<
2039< #Checks when privacy is INVITATION_ONLY
2040< e_id3 = auto_make_test_event(
2041< u_id1,
2042< privacy_setting=api.EvPrivacy.INVITATION_ONLY,
2043< invitees=[u_id3, u_id5])
2044< api.user_like_event(sesh, u_id1, e_id3) #Host cannot like own event
2045< self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id3))
2046< api.user_like_event(sesh, u_id2,
2047< e_id3) #Non-invited non-follower cannot like event
2048< self.assertFalse(api.user_check_like_event(sesh, u_id2, e_id3))
2049< api.user_like_event(sesh, u_id3,
2050< e_id3) #Invited non-follower can like event
2051< self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id3))
2052< api.user_like_event(sesh, u_id4,
2053< e_id3) #Non-invited follower cannot like event
2054< self.assertFalse(api.user_check_like_event(sesh, u_id4, e_id3))
2055< api.user_like_event(sesh, u_id5,
2056< e_id3) #Invited follower can like event
2057< self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id3))
2058<
2059< def test_declare_interest(self):
2060< refresh()
2061< sesh = api.get_session()
2062< u_id1 = generate_test_user()
2063< u_id2 = generate_test_user()
2064< u_id3 = generate_test_user()
2065< u_id4 = generate_test_user()
2066< u_id5 = generate_test_user()
2067< api.user_follow_user(sesh, u_id4, u_id1)
2068< api.user_follow_user(sesh, u_id5, u_id1)
2069< #Checks when privacy is PUBLIC
2070< e_id1 = auto_make_test_event(u_id1,
2071< privacy_setting=api.EvPrivacy.PUBLIC,
2072< invitees=[u_id3, u_id5])
2073< api.user_declare_interest(
2074< sesh, u_id1, e_id1) #Host cannot declare interest in own event
2075< self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id1))
2076< api.user_declare_interest(
2077< sesh, u_id2,
2078< e_id1) #Non-invited non-follower can declare interest in event
2079< self.assertTrue(api.user_check_declared_interest(sesh, u_id2, e_id1))
2080< api.user_declare_interest(
2081< sesh, u_id3,
2082< e_id1) #Invited non-follower can declare interest event
2083< self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id1))
2084< api.user_declare_interest(
2085< sesh, u_id4,
2086< e_id1) #Non-invited follower can declare interest in event
2087< self.assertTrue(api.user_check_declared_interest(sesh, u_id4, e_id1))
2088< api.user_declare_interest(
2089< sesh, u_id5,
2090< e_id1) #Invited follower can declare interest in event
2091< self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id1))
2092< #Checks when privacy is FOLLOWERS_ONLY
2093< e_id2 = auto_make_test_event(
2094< u_id1,
2095< privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
2096< invitees=[u_id3, u_id5])
2097< api.user_declare_interest(
2098< sesh, u_id1, e_id2) #Host cannot declare interest in own event
2099< self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id2))
2100< api.user_declare_interest(
2101< sesh, u_id2,
2102< e_id2) #Non-invited non-follower cannot declare interest in event
2103< self.assertFalse(api.user_check_declared_interest(sesh, u_id2, e_id2))
2104< api.user_declare_interest(
2105< sesh, u_id3,
2106< e_id2) #Invited non-follower can declare interest event
2107< self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id2))
2108< api.user_declare_interest(
2109< sesh, u_id4,
2110< e_id2) #Non-invited follower can declare interest in event
2111< self.assertTrue(api.user_check_declared_interest(sesh, u_id4, e_id2))
2112< api.user_declare_interest(
2113< sesh, u_id5,
2114< e_id2) #Invited follower can declare interest in event
2115< self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id2))
2116< #Checks when privacy is INVITATION_ONLY
2117< e_id3 = auto_make_test_event(
2118< u_id1,
2119< privacy_setting=api.EvPrivacy.INVITATION_ONLY,
2120< invitees=[u_id3, u_id5])
2121< api.user_declare_interest(
2122< sesh, u_id1, e_id3) #Host cannot declare interest in own event
2123< self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id3))
2124< api.user_declare_interest(
2125< sesh, u_id2,
2126< e_id3) #Non-invited non-follower cannot declare interest in event
2127< self.assertFalse(api.user_check_declared_interest(sesh, u_id2, e_id3))
2128< api.user_declare_interest(
2129< sesh, u_id3,
2130< e_id3) #Invited non-follower can declare interest event
2131< self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id3))
2132< api.user_declare_interest(
2133< sesh, u_id4,
2134< e_id3) #Non-invited follower cannot declare interest in event
2135< self.assertFalse(api.user_check_declared_interest(sesh, u_id4, e_id3))
2136< api.user_declare_interest(
2137< sesh, u_id5,
2138< e_id3) #Invited follower can declare interest in event
2139< self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id3))
2140<
2141< def test_declare_going(self):
2142< refresh()
2143< sesh = api.get_session()
2144< u_id1 = generate_test_user()
2145< u_id2 = generate_test_user()
2146< u_id3 = generate_test_user()
2147< u_id4 = generate_test_user()
2148< u_id5 = generate_test_user()
2149< u_id6 = generate_test_user()
2150< u_id7 = generate_test_user()
2151< u_id8 = generate_test_user()
2152< u_id9 = generate_test_user()
2153<
2154< api.user_follow_user(sesh, u_id4, u_id1)
2155< api.user_follow_user(sesh, u_id5, u_id1)
2156< api.user_follow_user(sesh, u_id8, u_id1)
2157< api.user_follow_user(sesh, u_id9, u_id1)
2158< #Checks when privacy is PUBLIC and event has not yet ended
2159< e_id1 = auto_make_test_event(u_id1,
2160< privacy_setting=api.EvPrivacy.PUBLIC,
2161< invitees=[u_id3, u_id5, u_id7, u_id9])
2162< api.user_declare_interest(sesh, u_id6, e_id1)
2163< api.user_declare_interest(sesh, u_id7, e_id1)
2164< api.user_declare_interest(sesh, u_id8, e_id1)
2165< api.user_declare_interest(sesh, u_id9, e_id1)
2166<
2167< api.user_declare_going(sesh, u_id1,
2168< e_id1) #Host cannot declare going to own event
2169< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2170< api.user_declare_going(
2171< sesh, u_id2,
2172< e_id1) #Non-invited non-follower can declare going to event
2173< self.assertTrue(api.user_check_declared_going(sesh, u_id2, e_id1))
2174< api.user_declare_going(
2175< sesh, u_id3, e_id1
2176< ) #Invited non-follower can declare going to event, removes invitation
2177< self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
2178< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
2179< api.user_declare_going(
2180< sesh, u_id4,
2181< e_id1) #Non-invited follower can declare going to event
2182< self.assertTrue(api.user_check_declared_going(sesh, u_id4, e_id1))
2183< api.user_declare_going(
2184< sesh, u_id5, e_id1
2185< ) #Invited follower can declare going to event, removes invitation
2186< self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
2187< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
2188<
2189< api.user_declare_going(
2190< sesh, u_id6, e_id1
2191< ) #Interested non-invited non-follower can declare going to event, removes interest
2192< self.assertTrue(api.user_check_declared_going(sesh, u_id2, e_id1))
2193< self.assertFalse(api.user_check_declared_interest(sesh, u_id6, e_id1))
2194< api.user_declare_going(
2195< sesh, u_id7, e_id1
2196< ) #Interested invited non-follower can declare going to event, removes invitation and interest
2197< self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
2198< self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
2199< self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
2200<
2201< api.user_declare_going(
2202< sesh, u_id8, e_id1
2203< ) # Interested non-invited follower can declare going to event, removes interest
2204< self.assertTrue(api.user_check_declared_going(sesh, u_id8, e_id1))
2205< self.assertFalse(api.user_check_declared_interest(sesh, u_id8, e_id1))
2206< api.user_declare_going(
2207< sesh, u_id9, e_id1
2208< ) #Interested invited follower can declare going to event, removes invitation and interest
2209< self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
2210< self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
2211< self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
2212<
2213< #Checks when privacy is PUBLIC and event has ended
2214< e_id1 = auto_make_test_event(
2215< u_id1,
2216< privacy_setting=api.EvPrivacy.PUBLIC,
2217< invitees=[u_id3, u_id5, u_id7, u_id9],
2218< start_time=datetime.now() - timedelta(2),
2219< end_time=datetime.now() - timedelta(1)
2220< ) #None can declare going, invitations and interests will not be removed.
2221< api.user_declare_interest(sesh, u_id6, e_id1)
2222< api.user_declare_interest(sesh, u_id7, e_id1)
2223< api.user_declare_interest(sesh, u_id8, e_id1)
2224< api.user_declare_interest(sesh, u_id9, e_id1)
2225< api.user_declare_going(sesh, u_id1, e_id1)
2226< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2227< api.user_declare_going(sesh, u_id2, e_id1)
2228< self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
2229< api.user_declare_going(sesh, u_id3, e_id1)
2230< self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
2231< self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
2232< api.user_declare_going(sesh, u_id4, e_id1)
2233< self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
2234< api.user_declare_going(sesh, u_id5, e_id1)
2235< self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
2236< self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
2237< api.user_declare_going(sesh, u_id6, e_id1)
2238< self.assertFalse(api.user_check_declared_going(sesh, u_id6, e_id1))
2239< self.assertTrue(api.user_check_declared_interest(sesh, u_id6, e_id1))
2240< api.user_declare_going(sesh, u_id7, e_id1)
2241< self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
2242< self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
2243< self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
2244< api.user_declare_going(sesh, u_id8, e_id1)
2245< self.assertFalse(api.user_check_declared_going(sesh, u_id8, e_id1))
2246< self.assertTrue(api.user_check_declared_interest(sesh, u_id8, e_id1))
2247< api.user_declare_going(sesh, u_id9, e_id1)
2248< self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
2249< self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
2250< self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
2251<
2252< #Checks when privacy is FOLLOWERS_ONLY and event has not yet ended
2253< e_id1 = auto_make_test_event(
2254< u_id1,
2255< privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
2256< invitees=[u_id3, u_id5, u_id7, u_id9])
2257< api.user_declare_interest(sesh, u_id7, e_id1)
2258< api.user_declare_interest(sesh, u_id8, e_id1)
2259< api.user_declare_interest(sesh, u_id9, e_id1)
2260<
2261< api.user_declare_going(sesh, u_id1,
2262< e_id1) #Host cannot declare going to own event
2263< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2264< api.user_declare_going(
2265< sesh, u_id2,
2266< e_id1) #Non-invited non-follower cannot declare going to event
2267< self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
2268< api.user_declare_going(
2269< sesh, u_id3, e_id1
2270< ) #Invited non-follower can declare going to event, removes invitation
2271< self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
2272< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
2273< api.user_declare_going(
2274< sesh, u_id4,
2275< e_id1) #Non-invited follower can declare going to event
2276< self.assertTrue(api.user_check_declared_going(sesh, u_id4, e_id1))
2277< api.user_declare_going(
2278< sesh, u_id5, e_id1
2279< ) #Invited follower can declare going to event, removes invitation
2280< self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
2281< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
2282<
2283< #No non-invited non-follower user can declare interest in this event.
2284<
2285< api.user_declare_going(
2286< sesh, u_id7, e_id1
2287< ) #Interested invited non-follower can declare going to event, removes invitation and interest
2288< self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
2289< self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
2290< self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
2291<
2292< api.user_declare_going(
2293< sesh, u_id8, e_id1
2294< ) # Interested non-invited follower can declare going to event, removes interest
2295< self.assertTrue(api.user_check_declared_going(sesh, u_id8, e_id1))
2296< self.assertFalse(api.user_check_declared_interest(sesh, u_id8, e_id1))
2297< api.user_declare_going(
2298< sesh, u_id9, e_id1
2299< ) #Interested invited follower can declare going to event, removes invitation and interest
2300< self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
2301< self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
2302< self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
2303<
2304< #Checks when privacy is FOLLOWERS_ONLY and event has ended
2305< e_id1 = auto_make_test_event(
2306< u_id1,
2307< privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
2308< invitees=[u_id3, u_id5, u_id7, u_id9],
2309< start_time=datetime.now() - timedelta(2),
2310< end_time=datetime.now() - timedelta(1)
2311< ) #None can declare going, invitations and interests will not be removed.
2312< api.user_declare_interest(sesh, u_id7, e_id1)
2313< api.user_declare_interest(sesh, u_id8, e_id1)
2314< api.user_declare_interest(sesh, u_id9, e_id1)
2315< api.user_declare_going(sesh, u_id1, e_id1)
2316< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2317< api.user_declare_going(sesh, u_id2, e_id1)
2318< self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
2319< api.user_declare_going(sesh, u_id3, e_id1)
2320< self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
2321< self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
2322< api.user_declare_going(sesh, u_id4, e_id1)
2323< self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
2324< api.user_declare_going(sesh, u_id5, e_id1)
2325< self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
2326< self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
2327<
2328< api.user_declare_going(sesh, u_id7, e_id1)
2329< self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
2330< self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
2331< self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
2332< api.user_declare_going(sesh, u_id8, e_id1)
2333< self.assertFalse(api.user_check_declared_going(sesh, u_id8, e_id1))
2334< self.assertTrue(api.user_check_declared_interest(sesh, u_id8, e_id1))
2335< api.user_declare_going(sesh, u_id9, e_id1)
2336< self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
2337< self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
2338< self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
2339<
2340< #Checks when privacy is INVITATION_ONLY and event has not yet ended
2341< e_id1 = auto_make_test_event(
2342< u_id1,
2343< privacy_setting=api.EvPrivacy.INVITATION_ONLY,
2344< invitees=[u_id3, u_id5, u_id7, u_id9])
2345< api.user_declare_interest(sesh, u_id7, e_id1)
2346< api.user_declare_interest(sesh, u_id9, e_id1)
2347<
2348< api.user_declare_going(sesh, u_id1,
2349< e_id1) #Host cannot declare going to own event
2350< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2351< api.user_declare_going(
2352< sesh, u_id2,
2353< e_id1) #Non-invited non-follower cannot declare going to event
2354< self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
2355< api.user_declare_going(
2356< sesh, u_id3, e_id1
2357< ) #Invited non-follower can declare going to event, removes invitation
2358< self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
2359< self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
2360< api.user_declare_going(
2361< sesh, u_id4,
2362< e_id1) #Non-invited follower cannot declare going to event
2363< self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
2364< api.user_declare_going(
2365< sesh, u_id5, e_id1
2366< ) #Invited follower can declare going to event, removes invitation
2367< self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
2368< self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
2369<
2370< #No non-invited non-follower user can declare interest in this event.
2371<
2372< api.user_declare_going(
2373< sesh, u_id7, e_id1
2374< ) #Interested invited non-follower can declare going to event, removes invitation and interest
2375< self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
2376< self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
2377< self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
2378<
2379< #No non-invited follower user can declare interest in this event.
2380<
2381< api.user_declare_going(
2382< sesh, u_id9, e_id1
2383< ) #Interested invited follower can declare going to event, removes invitation and interest
2384< self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
2385< self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
2386< self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
2387<
2388< #Checks when privacy is INVITATION_ONLY and event has ended
2389< e_id1 = auto_make_test_event(
2390< u_id1,
2391< privacy_setting=api.EvPrivacy.INVITATION_ONLY,
2392< invitees=[u_id3, u_id5, u_id7, u_id9],
2393< start_time=datetime.now() - timedelta(2),
2394< end_time=datetime.now() - timedelta(1)
2395< ) #None can declare going, invitations and interests will not be removed.
2396< api.user_declare_interest(sesh, u_id7, e_id1)
2397< api.user_declare_interest(sesh, u_id9, e_id1)
2398< api.user_declare_going(sesh, u_id1, e_id1)
2399< self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
2400< api.user_declare_going(sesh, u_id2, e_id1)
2401< self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
2402< api.user_declare_going(sesh, u_id3, e_id1)
2403< self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
2404< self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
2405< api.user_declare_going(sesh, u_id4, e_id1)
2406< self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
2407< api.user_declare_going(sesh, u_id5, e_id1)
2408< self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
2409< self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
2410<
2411< api.user_declare_going(sesh, u_id7, e_id1)
2412< self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
2413< self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
2414< self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
2415<
2416< api.user_declare_going(sesh, u_id9, e_id1)
2417< self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
2418< self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
2419< self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
2420<
2421< def test_user_accept_invitation(self):
2422< refresh()
2423< sesh = api.get_session()
2424< for priv_setting in api.EvPrivacy:
2425< u_id1 = generate_test_user()
2426< u_id2 = generate_test_user()
2427< u_id3 = generate_test_user()
2428< u_id4 = generate_test_user()
2429< u_id5 = generate_test_user()
2430< api.user_follow_user(sesh, u_id3, u_id1)
2431< api.user_follow_user(sesh, u_id5, u_id1)
2432< ev_id = auto_make_test_event(u_id1,
2433< privacy_setting=priv_setting,
2434< invitees=[u_id2, u_id3])
2435<
2436< api.user_accept_invitation(
2437< sesh, u_id1, ev_id
2438< ) #Host cannot accept invitation to own event (i.e. nothing happens when this function is called)
2439< self.assertFalse(api.user_check_invited_to(sesh, u_id1, ev_id))
2440< self.assertFalse(api.user_check_declared_going(sesh, u_id1, ev_id))
2441< api.user_accept_invitation(
2442< sesh, u_id2, ev_id
2443< ) #Invited non-follower can accept invitation, removing invitation.
2444< self.assertFalse(api.user_check_invited_to(sesh, u_id2, ev_id))
2445< self.assertTrue(api.user_check_declared_going(sesh, u_id2, ev_id))
2446< api.user_accept_invitation(
2447< sesh, u_id3, ev_id
2448< ) #Invited follower can accept invitation, removing invitation.
2449< self.assertFalse(api.user_check_invited_to(sesh, u_id3, ev_id))
2450< self.assertTrue(api.user_check_declared_going(sesh, u_id3, ev_id))
2451< api.user_accept_invitation(
2452< sesh, u_id4, ev_id
2453< ) #Non-invited non-follower cannot accept invitation, removing invitation.
2454< self.assertFalse(api.user_check_invited_to(sesh, u_id4, ev_id))
2455< self.assertFalse(api.user_check_declared_going(sesh, u_id4, ev_id))
2456< api.user_accept_invitation(
2457< sesh, u_id5, ev_id
2458< ) #Non-invited follower cannot accept invitation, removing invitation.
2459< self.assertFalse(api.user_check_invited_to(sesh, u_id5, ev_id))
2460< self.assertFalse(api.user_check_declared_going(sesh, u_id5, ev_id))
2461<
2462< def test_get_db_events_within_radius(self):
2463< refresh()
2464< sesh = api.get_session()
2465< u_id = generate_test_user()
2466< e_id1 = auto_make_test_event(u_id, event_lat=0.0, event_lng=0.0)
2467< evs_within_distance = api.get_db_events_within_radius(
2468< sesh, api.EvTags.DANCE.value, 0.0, 0.0, 10, u_id)
2469< self.assertEqual(len(evs_within_distance), 1)
2470<
2471< def test_populate_function_table(self):
2472< refresh()
2473< sesh = api.get_session()
2474< self.assertEqual(sesh.query(Function).count(), 0)
2475< scripts.populate_function_table()
2476< self.assertNotEqual(sesh.query(Function).count(), 0)
2477<
2478<
2479< if __name__ == '__main__':
2480< unittest.main()
2481---
2482> # pylint: skip-file
2483> import api
2484> from models import User, Event, Post, UU_relationship, UP_relationship, UE_relationship, Function, FunCall
2485> from datetime import datetime, timedelta
2486> import unittest
2487> from exceptions import UserAlreadyExistsError
2488> import scripts
2489>
2490> num_user = 0
2491> num_event = 0
2492> num_post = 0
2493>
2494>
2495> def generate_test_user(username="TestUser",
2496> password="TestPassword",
2497> first_name="Test",
2498> last_name="User",
2499> email="TestUser@card-way.com",
2500> phone_number="123-456-7890",
2501> birthday=datetime.now(),
2502> street_address="123, Bobrey Rd.",
2503> city="Rochester",
2504> state="NY",
2505> country="USA",
2506> zipcode="12345",
2507> company=False,
2508> salt=None):
2509> global num_user
2510> sesh = api.get_session()
2511> num_user += 1
2512> if username == "TestUser":
2513> username = "TestUser" + str(num_user)
2514> return api.user_post_new(sesh, username, password, first_name, last_name,
2515> email, phone_number, birthday, street_address,
2516> city, state, country, zipcode, company, salt)
2517>
2518>
2519> def auto_make_test_event(host_id,
2520> description="Come over, have fun!",
2521> start_time=datetime.now() - timedelta(1),
2522> end_time=datetime.now() + timedelta(1),
2523> location_name="Jonny's House",
2524> privacy_setting=api.EvPrivacy.PUBLIC,
2525> tag=api.EvTags.DANCE,
2526> event_lat=1.1,
2527> event_lng=2.2,
2528> active=True,
2529> company=False,
2530> promotion=False,
2531> hide=False,
2532> invitees=[]):
2533> sesh = api.get_session()
2534> return api.user_make_event(sesh,
2535> host_id,
2536> description=description,
2537> start_time=start_time,
2538> end_time=end_time,
2539> location_name=location_name,
2540> privacy_setting=privacy_setting,
2541> tag=tag,
2542> event_lat=event_lat,
2543> event_lng=event_lng,
2544> active=active,
2545> company=company,
2546> promotion=promotion,
2547> invited_users=invitees)
2548>
2549>
2550> def refresh():
2551> sesh = api.get_session()
2552> print(sesh.query(FunCall).count())
2553> sesh.query(User).delete()
2554> sesh.query(Event).delete()
2555> sesh.query(Post).delete()
2556> sesh.query(UU_relationship).delete()
2557> sesh.query(UE_relationship).delete()
2558> sesh.query(UP_relationship).delete()
2559> sesh.query(Function).delete()
2560> sesh.query(FunCall).delete()
2561> sesh.commit()
2562>
2563>
2564> class Testing(unittest.TestCase):
2565> def test_unit_post_new(self):
2566> refresh()
2567> sesh = api.get_session()
2568> cur_time = datetime.now()
2569> test_id = api.user_post_new(sesh, "user1", "BobJones", "Bob", "Jones", "BobJones123@hotmail.com", "565-567-6789",\
2570> cur_time, "213B Baker Street", "London", "NY", "USA", "12345", False)
2571> self.assertEqual(sesh.query(User).count(), 1)
2572> #We need to [_sa_instance_state] because each dict will be created with a new one, even if everything else
2573> #(including primary keys) are the same.
2574> test_user = sesh.query(User).filter(
2575> User.id == test_id).first().__dict__
2576> usr_salt = test_user['pass_hash_salt'].split('$')[2]
2577> check_user = User(username = "user1", pass_hash_salt = "$"+ api.hash_password("BobJones",usr_salt) + "$" + usr_salt,\
2578> first_name = "Bob", last_name = "Jones", email = "BobJones123@hotmail.com", phone = "565-567-6789",\
2579> street_address = "213B Baker Street", city = "London", state = "NY", country = "USA", zipcode = "12345",\
2580> birthday = cur_time, company = False, id = test_id).__dict__
2581> test_user.pop('_sa_instance_state')
2582> check_user.pop('_sa_instance_state')
2583>
2584> # print(str(test_user))
2585> # print("*************")
2586> # print(str(check_user))
2587> self.assertTrue(test_user == check_user)
2588> self.assertRaises(UserAlreadyExistsError, api.user_post_new, sesh, "user1", "BobJones2", "Bob2", "Jones2", "BobJones123@hotmail.com2", "565-567-67892",\
2589> cur_time, "213B Baker Street2", "London2", "NY2", "USA2", "123452", False, None)
2590>
2591> def test_event_post_new(self):
2592> refresh()
2593> cur_time = datetime.now()
2594> sesh = api.get_session()
2595> end_time = cur_time + timedelta(1)
2596> start_time = cur_time - timedelta(1)
2597> test_user_id = api.user_post_new(sesh, "user1", "BobJones", "Bob", "Jones", "BobJones123@hotmail.com", "565-567-6789",\
2598> cur_time, "213B Baker Street", "London", "NY", "USA", "12345", False)
2599> test_id = api.event_post_new(sesh, test_user_id, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
2600> 1.1,2.2, True, False, False, False, False, cur_time,)
2601> self.assertEqual(sesh.query(Event).count(), 1)
2602> test_event = sesh.query(Event).filter(
2603> Event.id == test_id).first().__dict__
2604> test_event.pop('_sa_instance_state')
2605> check_event = Event(id = test_id, host = test_user_id, location_name = "Jonny's House", description = "Come over for a fun time!", start_time = start_time,\
2606> end_time = end_time, privacy_setting = api.EvPrivacy.PUBLIC.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = cur_time,
2607> active = True, company = False, promotion = False, hide = False, location = False ).__dict__
2608> check_event.pop('_sa_instance_state')
2609> self.assertEqual(test_event, check_event)
2610>
2611> def test_user_follow_user(self):
2612> refresh()
2613> sesh = api.get_session()
2614> id1 = generate_test_user()
2615> id2 = generate_test_user()
2616> self.assertFalse(api.user_check_followee_of(sesh, id1, id2))
2617> self.assertFalse(api.user_check_followee_of(sesh, id2, id1))
2618> self.assertFalse(api.user_check_follower_of(sesh, id1, id2))
2619> self.assertFalse(api.user_check_follower_of(sesh, id2, id1))
2620> api.user_follow_user(sesh, id1, id2)
2621> self.assertEquals(sesh.query(FunCall).count(), 1)
2622> self.assertFalse(api.user_check_followee_of(sesh, id1, id2))
2623> self.assertTrue(api.user_check_followee_of(sesh, id2, id1))
2624> self.assertTrue(api.user_check_follower_of(sesh, id1, id2))
2625> self.assertFalse(api.user_check_follower_of(sesh, id2, id1))
2626> api.user_follow_user(sesh, id2, id1)
2627> self.assertTrue(api.user_check_followee_of(sesh, id1, id2))
2628> self.assertTrue(api.user_check_followee_of(sesh, id2, id1))
2629> self.assertTrue(api.user_check_follower_of(sesh, id1, id2))
2630> self.assertTrue(api.user_check_follower_of(sesh, id2, id1))
2631>
2632> def test_user_mutually_following(self):
2633> refresh()
2634> sesh = api.get_session()
2635> id1 = generate_test_user()
2636> id2 = generate_test_user()
2637> self.assertFalse(api.user_mutually_following(sesh, id1, id2))
2638> api.user_follow_user(sesh, id1, id2)
2639> self.assertFalse(api.user_mutually_following(sesh, id1, id2))
2640> api.user_follow_user(sesh, id2, id1)
2641> self.assertTrue(api.user_mutually_following(sesh, id2, id1))
2642>
2643> def test_num_same_followees(self):
2644> refresh()
2645> sesh = api.get_session()
2646> n = 10
2647> count = 0
2648> u_id1 = generate_test_user()
2649> u_id2 = generate_test_user()
2650> u_id3 = generate_test_user()
2651> # api.user_follow_user(sesh, u_id1,u_id3)
2652> # api.user_follow_user(sesh, u_id2,u_id3)
2653> # self.assertEqual(api.user_num_same_followees(sesh, u_id1,u_id2), 1)
2654> # self.assertEqual(api.user_num_same_followees(sesh, u_id2,u_id3), 0)
2655> # self.assertEqual(api.user_num_same_followees(sesh, u_id3,u_id1), 0)
2656> for i in range(n):
2657> u_id = generate_test_user()
2658> if i % 2 == 0:
2659> api.user_follow_user(sesh, u_id1, u_id)
2660> if i % 3 == 0:
2661> api.user_follow_user(sesh, u_id2, u_id)
2662> if i % 6 == 0:
2663> api.user_follow_user(sesh, u_id3, u_id)
2664> count = count + 1
2665> self.assertEqual(api.user_num_same_followees(sesh, u_id1, u_id2),
2666> count)
2667> self.assertEqual(api.user_num_same_followees(sesh, u_id2, u_id3),
2668> count)
2669> self.assertEqual(api.user_num_same_followees(sesh, u_id3, u_id1),
2670> count)
2671>
2672> def test_user_post_be_invited(self):
2673> refresh()
2674> sesh = api.get_session()
2675> u_id1 = generate_test_user()
2676> u_id2 = generate_test_user()
2677> cur_time = datetime.now()
2678> end_time = cur_time + timedelta(1)
2679> start_time = cur_time - timedelta(1)
2680> e_id1 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
2681> 1.1,2.2, True, False, False, False, False, cur_time)
2682> api.user_post_be_invited(sesh, u_id2, e_id1)
2683> self.assertTrue(api.user_check_invited_to(sesh, u_id2, e_id1))
2684>
2685> def test_user_invite_to_event(self):
2686> refresh()
2687> sesh = api.get_session()
2688> #Sets up user_relationships
2689> u_id1 = generate_test_user()
2690> u_id2 = generate_test_user()
2691> u_id3 = generate_test_user()
2692> u_id4 = generate_test_user()
2693> u_id5 = generate_test_user()
2694> u_id6 = generate_test_user()
2695> api.user_follow_user(sesh, u_id4, u_id1)
2696> api.user_follow_user(sesh, u_id5, u_id1)
2697> api.user_follow_user(sesh, u_id6, u_id1)
2698> cur_time = datetime.now()
2699> end_time = cur_time + timedelta(1)
2700> start_time = cur_time - timedelta(1)
2701>
2702> #Checks what happens when privacy is PUBLIC
2703> e_id1 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.PUBLIC, api.EvTags.DANCE,\
2704> 1.1,2.2, True, False, False, False, False, cur_time)
2705> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
2706> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
2707> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
2708> api.user_invite_to_event(sesh, u_id2, e_id1,
2709> u_id1) #Host cannot be invited to own event.
2710> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
2711> api.user_invite_to_event(sesh, u_id2, e_id1,
2712> u_id2) #User cannot invite self.
2713> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
2714> api.user_invite_to_event(sesh, u_id2, e_id1,
2715> u_id3) #User can invite other non-follower.
2716> self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
2717> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id1))
2718> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id1))
2719>
2720> #Checks what happens when privacy is FOLLOWERS_ONLY
2721> e_id2 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.FOLLOWERS_ONLY, api.EvTags.DANCE,\
2722> 1.1,2.2, True, False, False, False, False, cur_time)
2723> e_id3 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.FOLLOWERS_ONLY, api.EvTags.DANCE,\
2724> 1.1,2.2, True, False, False, False, False, cur_time)
2725> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2726> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2727> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
2728> api.user_invite_to_event(sesh, u_id2, e_id2,
2729> u_id1) #Host cannot be invited
2730> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2731> api.user_invite_to_event(sesh, u_id2, e_id2,
2732> u_id2) #User cannot invite self
2733> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2734> api.user_invite_to_event(
2735> sesh, u_id2, e_id2,
2736> u_id3) #Non-follower user cannot invite non-follower
2737> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
2738> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2739> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2740> api.user_invite_to_event(
2741> sesh, u_id2, e_id2,
2742> u_id4) #Non-user follower cannot invite follower
2743> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
2744> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
2745> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2746> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2747> api.user_invite_to_event(sesh, u_id4, e_id2,
2748> u_id3) #Follower cannot invite non-follower
2749> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
2750> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
2751> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2752> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2753> api.user_invite_to_event(sesh, u_id4, e_id2,
2754> u_id5) #Follower can invite follower
2755> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id2))
2756> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id2))
2757> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id2))
2758> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id2))
2759> self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id2))
2760> api.user_invite_to_event(sesh, u_id1, e_id3,
2761> u_id6) #Host can invite follower
2762> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id3))
2763> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id3))
2764> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id3))
2765> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id3))
2766> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id3))
2767> self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id3))
2768> api.user_invite_to_event(sesh, u_id1, e_id3,
2769> u_id3) #Host can invite non-follower
2770> self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id3))
2771> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id3))
2772> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id3))
2773>
2774> #Checks what happens when privacy is INVITATION ONLY
2775> e_id5 = api.event_post_new(sesh, u_id1, "Come over for a fun time!", start_time, end_time, "Jonny's House", api.EvPrivacy.INVITATION_ONLY, api.EvTags.DANCE,\
2776> 1.1,2.2, True, False, False, False, False, cur_time)
2777> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2778> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2779> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2780> api.user_invite_to_event(sesh, u_id2, e_id5,
2781> u_id1) #Non-follower cannot invite host
2782> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2783> api.user_invite_to_event(sesh, u_id2, e_id5,
2784> u_id2) #Non-follower cannot invite follower
2785> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2786> api.user_invite_to_event(
2787> sesh, u_id2, e_id5,
2788> u_id3) #Non-follower cannot invite non-follower
2789> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2790> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2791> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2792> api.user_invite_to_event(sesh, u_id2, e_id5,
2793> u_id4) #Non-follower cannot invite follower
2794> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
2795> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2796> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2797> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2798> api.user_invite_to_event(sesh, u_id4, e_id5,
2799> u_id3) #Follower cannot invite follower
2800> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
2801> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2802> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2803> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2804> api.user_invite_to_event(sesh, u_id4, e_id5,
2805> u_id5) #Follower cannot invite follower
2806> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
2807> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2808> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2809> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2810> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
2811> api.user_invite_to_event(sesh, u_id1, e_id5,
2812> u_id6) #Host can invite follower
2813> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
2814> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2815> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2816> self.assertFalse(api.user_check_invited_to(sesh, u_id2, e_id5))
2817> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
2818> self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id5))
2819> api.user_invite_to_event(sesh, u_id1, e_id5,
2820> u_id2) #Host can invite non-follower
2821> self.assertFalse(api.user_check_invited_to(sesh, u_id4, e_id5))
2822> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id5))
2823> self.assertFalse(api.user_check_invited_to(sesh, u_id1, e_id5))
2824> self.assertTrue(api.user_check_invited_to(sesh, u_id2, e_id5))
2825> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id5))
2826> self.assertTrue(api.user_check_invited_to(sesh, u_id6, e_id5))
2827>
2828> def test_user_make_event(self):
2829> refresh()
2830> sesh = api.get_session()
2831> #Runs the test one time for each privacy setting:
2832> for priv_setting in api.EvPrivacy:
2833> refresh()
2834> sesh = api.get_session()
2835> u_id1 = generate_test_user()
2836> u_id2 = generate_test_user()
2837> user_ids = []
2838> for i in range(10):
2839> user_ids.append(generate_test_user())
2840> if i % 2 == 0:
2841> api.user_follow_user(sesh, user_ids[i], u_id1)
2842> cur_time = datetime.now()
2843> end_time = cur_time + timedelta(1)
2844> start_time = cur_time - timedelta(1)
2845>
2846> #Checks when no users have been invited
2847> current_count = sesh.query(Event).count()
2848>
2849> ev_id = api.user_make_event(sesh, u_id1, "Come over, have fun!",
2850> start_time, end_time, "Jonny's House",
2851> priv_setting, api.EvTags.DANCE, 1.1,
2852> 2.2, True, False, False, [])
2853> self.assertEqual(sesh.query(Event).count(),
2854> current_count + 1) #Some event has been added
2855> api.check_event_exists(
2856> sesh, ev_id
2857> ) #id returned is valid event id (check_event_exists throws an error if not)
2858> new_event = sesh.query(Event).filter(
2859> Event.id == ev_id).first().__dict__
2860> new_event.pop('_sa_instance_state')
2861> check_event = Event(id = ev_id, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
2862> end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
2863> active = True, company = False, promotion = False, hide = False, location = False ).__dict__
2864> check_event.pop('_sa_instance_state')
2865>
2866> self.assertEqual(
2867> new_event,
2868> check_event) #Event with correct values has been added
2869> self.assertFalse(api.user_check_invited_to(
2870> sesh, u_id2, ev_id)) #u_id2 has not been invited
2871> for i in range(len(user_ids)): #No other users were invited
2872> self.assertFalse(
2873> api.user_check_invited_to(sesh, user_ids[i], ev_id))
2874>
2875> #Checks when one user has been invited
2876> current_count = sesh.query(Event).count()
2877>
2878> ev_id2 = api.user_make_event(sesh, u_id1, "Come over, have fun!",
2879> start_time, end_time, "Jonny's House",
2880> priv_setting, api.EvTags.DANCE, 1.1,
2881> 2.2, True, False, False, [u_id2])
2882>
2883> self.assertEqual(sesh.query(Event).count(),
2884> current_count + 1) #Some event has been added
2885> api.check_event_exists(
2886> sesh, ev_id2
2887> ) #id returned is valid event id (check_event_exists throws an error if not)
2888> new_event = sesh.query(Event).filter(
2889> Event.id == ev_id2).first().__dict__
2890> new_event.pop('_sa_instance_state')
2891> check_event = Event(id = ev_id2, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
2892> end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
2893> active = True, company = False, promotion = False, hide = False, location = False ).__dict__
2894> check_event.pop('_sa_instance_state')
2895> self.assertEqual(
2896> new_event,
2897> check_event) #Event with correct values has been added
2898> self.assertTrue(api.user_check_invited_to(
2899> sesh, u_id2, ev_id2)) #u_id2 was invited
2900> for i in range(len(user_ids)): #No other users were invited
2901> self.assertFalse(
2902> api.user_check_invited_to(sesh, user_ids[i], ev_id2))
2903>
2904> #Checks when 10 users have been invited
2905> current_count = sesh.query(Event).count()
2906>
2907> ev_id3 = api.user_make_event(sesh, u_id1, "Come over, have fun!",
2908> start_time, end_time, "Jonny's House",
2909> priv_setting, api.EvTags.DANCE, 1.1,
2910> 2.2, True, False, False, user_ids)
2911>
2912> self.assertEqual(sesh.query(Event).count(),
2913> current_count + 1) #Some event has been added
2914> api.check_event_exists(
2915> sesh, ev_id3
2916> ) #id returned is valid event id (check_event_exists throws an error if not)
2917> new_event = sesh.query(Event).filter(
2918> Event.id == ev_id3).first().__dict__
2919> new_event.pop('_sa_instance_state')
2920> check_event = Event(id = ev_id3, host = u_id1, location_name = "Jonny's House", description = "Come over, have fun!", start_time = start_time,\
2921> end_time = end_time, privacy_setting = priv_setting.value, tag = api.EvTags.DANCE.value, latitude = 1.1, longitude = 2.2, timestamp = new_event["timestamp"],
2922> active = True, company = False, promotion = False, hide = False, location = False ).__dict__
2923> check_event.pop('_sa_instance_state')
2924> self.assertEqual(
2925> new_event,
2926> check_event) #Event with correct values has been added
2927> self.assertFalse(api.user_check_invited_to(
2928> sesh, u_id2, ev_id3)) #u_id2 was not invited
2929> for i in range(len(user_ids)): #10 other users were invited
2930> self.assertTrue(
2931> api.user_check_invited_to(sesh, user_ids[i], ev_id3))
2932>
2933> def test_user_like_event(self):
2934> refresh()
2935> sesh = api.get_session()
2936> u_id1 = generate_test_user()
2937> u_id2 = generate_test_user()
2938> u_id3 = generate_test_user()
2939> u_id4 = generate_test_user()
2940> u_id5 = generate_test_user()
2941> api.user_follow_user(sesh, u_id4, u_id1)
2942> api.user_follow_user(sesh, u_id5, u_id1)
2943> #Checks when privacy is PUBLIC
2944> e_id1 = auto_make_test_event(u_id1,
2945> privacy_setting=api.EvPrivacy.PUBLIC,
2946> invitees=[u_id3, u_id5])
2947> api.user_like_event(sesh, u_id1, e_id1) #Host cannot like own event
2948> self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id1))
2949> api.user_like_event(sesh, u_id2,
2950> e_id1) #Non-invited non-follower can like event
2951> self.assertTrue(api.user_check_like_event(sesh, u_id2, e_id1))
2952> api.user_like_event(sesh, u_id3,
2953> e_id1) #Invited non-follower can like event
2954> self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id1))
2955> api.user_like_event(sesh, u_id4,
2956> e_id1) #Non-invited follower can like event
2957> self.assertTrue(api.user_check_like_event(sesh, u_id4, e_id1))
2958> api.user_like_event(sesh, u_id5,
2959> e_id1) #Invited follower can like event
2960> self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id1))
2961> #Checks when privacy is FOLLOWERS_ONLY
2962> e_id2 = auto_make_test_event(
2963> u_id1,
2964> privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
2965> invitees=[u_id3, u_id5])
2966> api.user_like_event(sesh, u_id1, e_id2) #Host cannot like own event
2967> self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id2))
2968> api.user_like_event(sesh, u_id2,
2969> e_id2) #Non-invited non-follower cannot like event
2970> self.assertFalse(api.user_check_like_event(sesh, u_id2, e_id2))
2971> api.user_like_event(sesh, u_id3,
2972> e_id2) #Invited non-follower can like event
2973> self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id2))
2974> api.user_like_event(sesh, u_id4,
2975> e_id2) #Non-invited follower can like event
2976> self.assertTrue(api.user_check_like_event(sesh, u_id4, e_id2))
2977> api.user_like_event(sesh, u_id5,
2978> e_id2) #Invited follower can like event
2979> self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id2))
2980>
2981> #Checks when privacy is INVITATION_ONLY
2982> e_id3 = auto_make_test_event(
2983> u_id1,
2984> privacy_setting=api.EvPrivacy.INVITATION_ONLY,
2985> invitees=[u_id3, u_id5])
2986> api.user_like_event(sesh, u_id1, e_id3) #Host cannot like own event
2987> self.assertFalse(api.user_check_like_event(sesh, u_id1, e_id3))
2988> api.user_like_event(sesh, u_id2,
2989> e_id3) #Non-invited non-follower cannot like event
2990> self.assertFalse(api.user_check_like_event(sesh, u_id2, e_id3))
2991> api.user_like_event(sesh, u_id3,
2992> e_id3) #Invited non-follower can like event
2993> self.assertTrue(api.user_check_like_event(sesh, u_id3, e_id3))
2994> api.user_like_event(sesh, u_id4,
2995> e_id3) #Non-invited follower cannot like event
2996> self.assertFalse(api.user_check_like_event(sesh, u_id4, e_id3))
2997> api.user_like_event(sesh, u_id5,
2998> e_id3) #Invited follower can like event
2999> self.assertTrue(api.user_check_like_event(sesh, u_id5, e_id3))
3000>
3001> def test_declare_interest(self):
3002> refresh()
3003> sesh = api.get_session()
3004> u_id1 = generate_test_user()
3005> u_id2 = generate_test_user()
3006> u_id3 = generate_test_user()
3007> u_id4 = generate_test_user()
3008> u_id5 = generate_test_user()
3009> api.user_follow_user(sesh, u_id4, u_id1)
3010> api.user_follow_user(sesh, u_id5, u_id1)
3011> #Checks when privacy is PUBLIC
3012> e_id1 = auto_make_test_event(u_id1,
3013> privacy_setting=api.EvPrivacy.PUBLIC,
3014> invitees=[u_id3, u_id5])
3015> api.user_declare_interest(
3016> sesh, u_id1, e_id1) #Host cannot declare interest in own event
3017> self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id1))
3018> api.user_declare_interest(
3019> sesh, u_id2,
3020> e_id1) #Non-invited non-follower can declare interest in event
3021> self.assertTrue(api.user_check_declared_interest(sesh, u_id2, e_id1))
3022> api.user_declare_interest(
3023> sesh, u_id3,
3024> e_id1) #Invited non-follower can declare interest event
3025> self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id1))
3026> api.user_declare_interest(
3027> sesh, u_id4,
3028> e_id1) #Non-invited follower can declare interest in event
3029> self.assertTrue(api.user_check_declared_interest(sesh, u_id4, e_id1))
3030> api.user_declare_interest(
3031> sesh, u_id5,
3032> e_id1) #Invited follower can declare interest in event
3033> self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id1))
3034> #Checks when privacy is FOLLOWERS_ONLY
3035> e_id2 = auto_make_test_event(
3036> u_id1,
3037> privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
3038> invitees=[u_id3, u_id5])
3039> api.user_declare_interest(
3040> sesh, u_id1, e_id2) #Host cannot declare interest in own event
3041> self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id2))
3042> api.user_declare_interest(
3043> sesh, u_id2,
3044> e_id2) #Non-invited non-follower cannot declare interest in event
3045> self.assertFalse(api.user_check_declared_interest(sesh, u_id2, e_id2))
3046> api.user_declare_interest(
3047> sesh, u_id3,
3048> e_id2) #Invited non-follower can declare interest event
3049> self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id2))
3050> api.user_declare_interest(
3051> sesh, u_id4,
3052> e_id2) #Non-invited follower can declare interest in event
3053> self.assertTrue(api.user_check_declared_interest(sesh, u_id4, e_id2))
3054> api.user_declare_interest(
3055> sesh, u_id5,
3056> e_id2) #Invited follower can declare interest in event
3057> self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id2))
3058> #Checks when privacy is INVITATION_ONLY
3059> e_id3 = auto_make_test_event(
3060> u_id1,
3061> privacy_setting=api.EvPrivacy.INVITATION_ONLY,
3062> invitees=[u_id3, u_id5])
3063> api.user_declare_interest(
3064> sesh, u_id1, e_id3) #Host cannot declare interest in own event
3065> self.assertFalse(api.user_check_declared_interest(sesh, u_id1, e_id3))
3066> api.user_declare_interest(
3067> sesh, u_id2,
3068> e_id3) #Non-invited non-follower cannot declare interest in event
3069> self.assertFalse(api.user_check_declared_interest(sesh, u_id2, e_id3))
3070> api.user_declare_interest(
3071> sesh, u_id3,
3072> e_id3) #Invited non-follower can declare interest event
3073> self.assertTrue(api.user_check_declared_interest(sesh, u_id3, e_id3))
3074> api.user_declare_interest(
3075> sesh, u_id4,
3076> e_id3) #Non-invited follower cannot declare interest in event
3077> self.assertFalse(api.user_check_declared_interest(sesh, u_id4, e_id3))
3078> api.user_declare_interest(
3079> sesh, u_id5,
3080> e_id3) #Invited follower can declare interest in event
3081> self.assertTrue(api.user_check_declared_interest(sesh, u_id5, e_id3))
3082>
3083> def test_declare_going(self):
3084> refresh()
3085> sesh = api.get_session()
3086> u_id1 = generate_test_user()
3087> u_id2 = generate_test_user()
3088> u_id3 = generate_test_user()
3089> u_id4 = generate_test_user()
3090> u_id5 = generate_test_user()
3091> u_id6 = generate_test_user()
3092> u_id7 = generate_test_user()
3093> u_id8 = generate_test_user()
3094> u_id9 = generate_test_user()
3095>
3096> api.user_follow_user(sesh, u_id4, u_id1)
3097> api.user_follow_user(sesh, u_id5, u_id1)
3098> api.user_follow_user(sesh, u_id8, u_id1)
3099> api.user_follow_user(sesh, u_id9, u_id1)
3100> #Checks when privacy is PUBLIC and event has not yet ended
3101> e_id1 = auto_make_test_event(u_id1,
3102> privacy_setting=api.EvPrivacy.PUBLIC,
3103> invitees=[u_id3, u_id5, u_id7, u_id9])
3104> api.user_declare_interest(sesh, u_id6, e_id1)
3105> api.user_declare_interest(sesh, u_id7, e_id1)
3106> api.user_declare_interest(sesh, u_id8, e_id1)
3107> api.user_declare_interest(sesh, u_id9, e_id1)
3108>
3109> api.user_declare_going(sesh, u_id1,
3110> e_id1) #Host cannot declare going to own event
3111> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3112> api.user_declare_going(
3113> sesh, u_id2,
3114> e_id1) #Non-invited non-follower can declare going to event
3115> self.assertTrue(api.user_check_declared_going(sesh, u_id2, e_id1))
3116> api.user_declare_going(
3117> sesh, u_id3, e_id1
3118> ) #Invited non-follower can declare going to event, removes invitation
3119> self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
3120> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
3121> api.user_declare_going(
3122> sesh, u_id4,
3123> e_id1) #Non-invited follower can declare going to event
3124> self.assertTrue(api.user_check_declared_going(sesh, u_id4, e_id1))
3125> api.user_declare_going(
3126> sesh, u_id5, e_id1
3127> ) #Invited follower can declare going to event, removes invitation
3128> self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
3129> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
3130>
3131> api.user_declare_going(
3132> sesh, u_id6, e_id1
3133> ) #Interested non-invited non-follower can declare going to event, removes interest
3134> self.assertTrue(api.user_check_declared_going(sesh, u_id2, e_id1))
3135> self.assertFalse(api.user_check_declared_interest(sesh, u_id6, e_id1))
3136> api.user_declare_going(
3137> sesh, u_id7, e_id1
3138> ) #Interested invited non-follower can declare going to event, removes invitation and interest
3139> self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
3140> self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
3141> self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
3142>
3143> api.user_declare_going(
3144> sesh, u_id8, e_id1
3145> ) # Interested non-invited follower can declare going to event, removes interest
3146> self.assertTrue(api.user_check_declared_going(sesh, u_id8, e_id1))
3147> self.assertFalse(api.user_check_declared_interest(sesh, u_id8, e_id1))
3148> api.user_declare_going(
3149> sesh, u_id9, e_id1
3150> ) #Interested invited follower can declare going to event, removes invitation and interest
3151> self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
3152> self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
3153> self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
3154>
3155> #Checks when privacy is PUBLIC and event has ended
3156> e_id1 = auto_make_test_event(
3157> u_id1,
3158> privacy_setting=api.EvPrivacy.PUBLIC,
3159> invitees=[u_id3, u_id5, u_id7, u_id9],
3160> start_time=datetime.now() - timedelta(2),
3161> end_time=datetime.now() - timedelta(1)
3162> ) #None can declare going, invitations and interests will not be removed.
3163> api.user_declare_interest(sesh, u_id6, e_id1)
3164> api.user_declare_interest(sesh, u_id7, e_id1)
3165> api.user_declare_interest(sesh, u_id8, e_id1)
3166> api.user_declare_interest(sesh, u_id9, e_id1)
3167> api.user_declare_going(sesh, u_id1, e_id1)
3168> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3169> api.user_declare_going(sesh, u_id2, e_id1)
3170> self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
3171> api.user_declare_going(sesh, u_id3, e_id1)
3172> self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
3173> self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
3174> api.user_declare_going(sesh, u_id4, e_id1)
3175> self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
3176> api.user_declare_going(sesh, u_id5, e_id1)
3177> self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
3178> self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
3179> api.user_declare_going(sesh, u_id6, e_id1)
3180> self.assertFalse(api.user_check_declared_going(sesh, u_id6, e_id1))
3181> self.assertTrue(api.user_check_declared_interest(sesh, u_id6, e_id1))
3182> api.user_declare_going(sesh, u_id7, e_id1)
3183> self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
3184> self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
3185> self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
3186> api.user_declare_going(sesh, u_id8, e_id1)
3187> self.assertFalse(api.user_check_declared_going(sesh, u_id8, e_id1))
3188> self.assertTrue(api.user_check_declared_interest(sesh, u_id8, e_id1))
3189> api.user_declare_going(sesh, u_id9, e_id1)
3190> self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
3191> self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
3192> self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
3193>
3194> #Checks when privacy is FOLLOWERS_ONLY and event has not yet ended
3195> e_id1 = auto_make_test_event(
3196> u_id1,
3197> privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
3198> invitees=[u_id3, u_id5, u_id7, u_id9])
3199> api.user_declare_interest(sesh, u_id7, e_id1)
3200> api.user_declare_interest(sesh, u_id8, e_id1)
3201> api.user_declare_interest(sesh, u_id9, e_id1)
3202>
3203> api.user_declare_going(sesh, u_id1,
3204> e_id1) #Host cannot declare going to own event
3205> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3206> api.user_declare_going(
3207> sesh, u_id2,
3208> e_id1) #Non-invited non-follower cannot declare going to event
3209> self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
3210> api.user_declare_going(
3211> sesh, u_id3, e_id1
3212> ) #Invited non-follower can declare going to event, removes invitation
3213> self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
3214> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
3215> api.user_declare_going(
3216> sesh, u_id4,
3217> e_id1) #Non-invited follower can declare going to event
3218> self.assertTrue(api.user_check_declared_going(sesh, u_id4, e_id1))
3219> api.user_declare_going(
3220> sesh, u_id5, e_id1
3221> ) #Invited follower can declare going to event, removes invitation
3222> self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
3223> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
3224>
3225> #No non-invited non-follower user can declare interest in this event.
3226>
3227> api.user_declare_going(
3228> sesh, u_id7, e_id1
3229> ) #Interested invited non-follower can declare going to event, removes invitation and interest
3230> self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
3231> self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
3232> self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
3233>
3234> api.user_declare_going(
3235> sesh, u_id8, e_id1
3236> ) # Interested non-invited follower can declare going to event, removes interest
3237> self.assertTrue(api.user_check_declared_going(sesh, u_id8, e_id1))
3238> self.assertFalse(api.user_check_declared_interest(sesh, u_id8, e_id1))
3239> api.user_declare_going(
3240> sesh, u_id9, e_id1
3241> ) #Interested invited follower can declare going to event, removes invitation and interest
3242> self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
3243> self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
3244> self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
3245>
3246> #Checks when privacy is FOLLOWERS_ONLY and event has ended
3247> e_id1 = auto_make_test_event(
3248> u_id1,
3249> privacy_setting=api.EvPrivacy.FOLLOWERS_ONLY,
3250> invitees=[u_id3, u_id5, u_id7, u_id9],
3251> start_time=datetime.now() - timedelta(2),
3252> end_time=datetime.now() - timedelta(1)
3253> ) #None can declare going, invitations and interests will not be removed.
3254> api.user_declare_interest(sesh, u_id7, e_id1)
3255> api.user_declare_interest(sesh, u_id8, e_id1)
3256> api.user_declare_interest(sesh, u_id9, e_id1)
3257> api.user_declare_going(sesh, u_id1, e_id1)
3258> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3259> api.user_declare_going(sesh, u_id2, e_id1)
3260> self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
3261> api.user_declare_going(sesh, u_id3, e_id1)
3262> self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
3263> self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
3264> api.user_declare_going(sesh, u_id4, e_id1)
3265> self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
3266> api.user_declare_going(sesh, u_id5, e_id1)
3267> self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
3268> self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
3269>
3270> api.user_declare_going(sesh, u_id7, e_id1)
3271> self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
3272> self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
3273> self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
3274> api.user_declare_going(sesh, u_id8, e_id1)
3275> self.assertFalse(api.user_check_declared_going(sesh, u_id8, e_id1))
3276> self.assertTrue(api.user_check_declared_interest(sesh, u_id8, e_id1))
3277> api.user_declare_going(sesh, u_id9, e_id1)
3278> self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
3279> self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
3280> self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
3281>
3282> #Checks when privacy is INVITATION_ONLY and event has not yet ended
3283> e_id1 = auto_make_test_event(
3284> u_id1,
3285> privacy_setting=api.EvPrivacy.INVITATION_ONLY,
3286> invitees=[u_id3, u_id5, u_id7, u_id9])
3287> api.user_declare_interest(sesh, u_id7, e_id1)
3288> api.user_declare_interest(sesh, u_id9, e_id1)
3289>
3290> api.user_declare_going(sesh, u_id1,
3291> e_id1) #Host cannot declare going to own event
3292> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3293> api.user_declare_going(
3294> sesh, u_id2,
3295> e_id1) #Non-invited non-follower cannot declare going to event
3296> self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
3297> api.user_declare_going(
3298> sesh, u_id3, e_id1
3299> ) #Invited non-follower can declare going to event, removes invitation
3300> self.assertTrue(api.user_check_declared_going(sesh, u_id3, e_id1))
3301> self.assertFalse(api.user_check_invited_to(sesh, u_id3, e_id1))
3302> api.user_declare_going(
3303> sesh, u_id4,
3304> e_id1) #Non-invited follower cannot declare going to event
3305> self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
3306> api.user_declare_going(
3307> sesh, u_id5, e_id1
3308> ) #Invited follower can declare going to event, removes invitation
3309> self.assertTrue(api.user_check_declared_going(sesh, u_id5, e_id1))
3310> self.assertFalse(api.user_check_invited_to(sesh, u_id5, e_id1))
3311>
3312> #No non-invited non-follower user can declare interest in this event.
3313>
3314> api.user_declare_going(
3315> sesh, u_id7, e_id1
3316> ) #Interested invited non-follower can declare going to event, removes invitation and interest
3317> self.assertTrue(api.user_check_declared_going(sesh, u_id7, e_id1))
3318> self.assertFalse(api.user_check_invited_to(sesh, u_id7, e_id1))
3319> self.assertFalse(api.user_check_declared_interest(sesh, u_id7, e_id1))
3320>
3321> #No non-invited follower user can declare interest in this event.
3322>
3323> api.user_declare_going(
3324> sesh, u_id9, e_id1
3325> ) #Interested invited follower can declare going to event, removes invitation and interest
3326> self.assertTrue(api.user_check_declared_going(sesh, u_id9, e_id1))
3327> self.assertFalse(api.user_check_invited_to(sesh, u_id9, e_id1))
3328> self.assertFalse(api.user_check_declared_interest(sesh, u_id9, e_id1))
3329>
3330> #Checks when privacy is INVITATION_ONLY and event has ended
3331> e_id1 = auto_make_test_event(
3332> u_id1,
3333> privacy_setting=api.EvPrivacy.INVITATION_ONLY,
3334> invitees=[u_id3, u_id5, u_id7, u_id9],
3335> start_time=datetime.now() - timedelta(2),
3336> end_time=datetime.now() - timedelta(1)
3337> ) #None can declare going, invitations and interests will not be removed.
3338> api.user_declare_interest(sesh, u_id7, e_id1)
3339> api.user_declare_interest(sesh, u_id9, e_id1)
3340> api.user_declare_going(sesh, u_id1, e_id1)
3341> self.assertFalse(api.user_check_declared_going(sesh, u_id1, e_id1))
3342> api.user_declare_going(sesh, u_id2, e_id1)
3343> self.assertFalse(api.user_check_declared_going(sesh, u_id2, e_id1))
3344> api.user_declare_going(sesh, u_id3, e_id1)
3345> self.assertFalse(api.user_check_declared_going(sesh, u_id3, e_id1))
3346> self.assertTrue(api.user_check_invited_to(sesh, u_id3, e_id1))
3347> api.user_declare_going(sesh, u_id4, e_id1)
3348> self.assertFalse(api.user_check_declared_going(sesh, u_id4, e_id1))
3349> api.user_declare_going(sesh, u_id5, e_id1)
3350> self.assertFalse(api.user_check_declared_going(sesh, u_id5, e_id1))
3351> self.assertTrue(api.user_check_invited_to(sesh, u_id5, e_id1))
3352>
3353> api.user_declare_going(sesh, u_id7, e_id1)
3354> self.assertFalse(api.user_check_declared_going(sesh, u_id7, e_id1))
3355> self.assertTrue(api.user_check_invited_to(sesh, u_id7, e_id1))
3356> self.assertTrue(api.user_check_declared_interest(sesh, u_id7, e_id1))
3357>
3358> api.user_declare_going(sesh, u_id9, e_id1)
3359> self.assertFalse(api.user_check_declared_going(sesh, u_id9, e_id1))
3360> self.assertTrue(api.user_check_invited_to(sesh, u_id9, e_id1))
3361> self.assertTrue(api.user_check_declared_interest(sesh, u_id9, e_id1))
3362>
3363> def test_user_accept_invitation(self):
3364> refresh()
3365> sesh = api.get_session()
3366> for priv_setting in api.EvPrivacy:
3367> u_id1 = generate_test_user()
3368> u_id2 = generate_test_user()
3369> u_id3 = generate_test_user()
3370> u_id4 = generate_test_user()
3371> u_id5 = generate_test_user()
3372> api.user_follow_user(sesh, u_id3, u_id1)
3373> api.user_follow_user(sesh, u_id5, u_id1)
3374> ev_id = auto_make_test_event(u_id1,
3375> privacy_setting=priv_setting,
3376> invitees=[u_id2, u_id3])
3377>
3378> api.user_accept_invitation(
3379> sesh, u_id1, ev_id
3380> ) #Host cannot accept invitation to own event (i.e. nothing happens when this function is called)
3381> self.assertFalse(api.user_check_invited_to(sesh, u_id1, ev_id))
3382> self.assertFalse(api.user_check_declared_going(sesh, u_id1, ev_id))
3383> api.user_accept_invitation(
3384> sesh, u_id2, ev_id
3385> ) #Invited non-follower can accept invitation, removing invitation.
3386> self.assertFalse(api.user_check_invited_to(sesh, u_id2, ev_id))
3387> self.assertTrue(api.user_check_declared_going(sesh, u_id2, ev_id))
3388> api.user_accept_invitation(
3389> sesh, u_id3, ev_id
3390> ) #Invited follower can accept invitation, removing invitation.
3391> self.assertFalse(api.user_check_invited_to(sesh, u_id3, ev_id))
3392> self.assertTrue(api.user_check_declared_going(sesh, u_id3, ev_id))
3393> api.user_accept_invitation(
3394> sesh, u_id4, ev_id
3395> ) #Non-invited non-follower cannot accept invitation, removing invitation.
3396> self.assertFalse(api.user_check_invited_to(sesh, u_id4, ev_id))
3397> self.assertFalse(api.user_check_declared_going(sesh, u_id4, ev_id))
3398> api.user_accept_invitation(
3399> sesh, u_id5, ev_id
3400> ) #Non-invited follower cannot accept invitation, removing invitation.
3401> self.assertFalse(api.user_check_invited_to(sesh, u_id5, ev_id))
3402> self.assertFalse(api.user_check_declared_going(sesh, u_id5, ev_id))
3403>
3404> def test_get_db_events_within_radius(self):
3405> refresh()
3406> sesh = api.get_session()
3407> u_id = generate_test_user()
3408> e_id1 = auto_make_test_event(u_id, event_lat=0.0, event_lng=0.0)
3409> evs_within_distance = api.get_db_events_within_radius(
3410> sesh, api.EvTags.DANCE.value, 0.0, 0.0, 10, u_id)
3411> self.assertEqual(len(evs_within_distance), 1)
3412>
3413> def test_populate_function_table(self):
3414> refresh()
3415> sesh = api.get_session()
3416> self.assertEqual(sesh.query(Function).count(), 0)
3417> scripts.populate_function_table()
3418> self.assertNotEqual(sesh.query(Function).count(), 0)
3419>
3420>
3421> if __name__ == '__main__':
3422> unittest.main()
3423diff -r COPY/utils/business.py cardway_backend/utils/business.py
34241,66c1,66
3425< """
3426< Holds implementation details for businesses mainly involving CRUD
3427< operations and other external facing data accesses.
3428< """
3429< from typing import Dict
3430< from database.main import get_database, get_db_name
3431< from models import business as models
3432< from models import commons
3433< import utils.commons as commons_util
3434<
3435< db = get_database()
3436< COLLECTION_NAME = "business"
3437< collection = db[get_db_name()][COLLECTION_NAME]
3438<
3439<
3440< # registers business with default location set and returns str(uuid)
3441< # TODO: set location of business either from coords or from address
3442< async def register_business(form: models.BusinessRegistrationForm) -> str:
3443< valid_business = await registration_form_to_business(form)
3444<
3445< business_dict = valid_business.dict()
3446< business_id = business_dict["id"]
3447<
3448< # FIXME: the `id` bug shows up once more;
3449< # this is a very temporary fix until we finally squash it in mongo.
3450< await commons_util.fix_dict_id_key_and_value(business_dict)
3451<
3452< collection.insert_one(business_dict)
3453< return business_id
3454<
3455<
3456< async def registration_form_to_business(
3457< form: models.BusinessRegistrationForm) -> models.Business:
3458< business_dict = form.dict()
3459< await set_location_for_business_dict(business_dict)
3460< return models.Business(**business_dict)
3461<
3462<
3463< async def get_business_by_id(business_id: commons.UserId) -> models.Business:
3464< query = await get_default_query(business_id)
3465< document = collection.find_one(query)
3466< if not document:
3467< raise Exception(f"Business with id {business_id} not found!")
3468< return models.Business(**document)
3469<
3470<
3471< async def set_location_for_business_dict(
3472< business_dict: Dict[str, str]) -> None:
3473< address = business_dict["street_address"]
3474< location = await get_location_cords_from_address(address)
3475< business_dict["location"] = location
3476<
3477<
3478< async def get_default_query(
3479< business_id: commons.UserId) -> Dict[str, commons.UserId]:
3480< return {"_id": business_id}
3481<
3482<
3483< async def get_location_cords_from_address(address: str) -> commons.Location:
3484< """
3485< Uses geopy (or other geoloc tool) to get a valid `Location` object from
3486< an address string
3487< """
3488< del address
3489< return commons.Location(lat=22.22,
3490< lng=33.33) # FIXME! Not actually implemented
3491---
3492> """
3493> Holds implementation details for businesses mainly involving CRUD
3494> operations and other external facing data accesses.
3495> """
3496> from typing import Dict
3497> from database.main import get_database, get_db_name
3498> from models import business as models
3499> from models import commons
3500> import utils.commons as commons_util
3501>
3502> db = get_database()
3503> COLLECTION_NAME = "business"
3504> collection = db[get_db_name()][COLLECTION_NAME]
3505>
3506>
3507> # registers business with default location set and returns str(uuid)
3508> # TODO: set location of business either from coords or from address
3509> async def register_business(form: models.BusinessRegistrationForm) -> str:
3510> valid_business = await registration_form_to_business(form)
3511>
3512> business_dict = valid_business.dict()
3513> business_id = business_dict["id"]
3514>
3515> # FIXME: the `id` bug shows up once more;
3516> # this is a very temporary fix until we finally squash it in mongo.
3517> await commons_util.fix_dict_id_key_and_value(business_dict)
3518>
3519> collection.insert_one(business_dict)
3520> return business_id
3521>
3522>
3523> async def registration_form_to_business(
3524> form: models.BusinessRegistrationForm) -> models.Business:
3525> business_dict = form.dict()
3526> await set_location_for_business_dict(business_dict)
3527> return models.Business(**business_dict)
3528>
3529>
3530> async def get_business_by_id(business_id: commons.UserId) -> models.Business:
3531> query = await get_default_query(business_id)
3532> document = collection.find_one(query)
3533> if not document:
3534> raise Exception(f"Business with id {business_id} not found!")
3535> return models.Business(**document)
3536>
3537>
3538> async def set_location_for_business_dict(
3539> business_dict: Dict[str, str]) -> None:
3540> address = business_dict["street_address"]
3541> location = await get_location_cords_from_address(address)
3542> business_dict["location"] = location
3543>
3544>
3545> async def get_default_query(
3546> business_id: commons.UserId) -> Dict[str, commons.UserId]:
3547> return {"_id": business_id}
3548>
3549>
3550> async def get_location_cords_from_address(address: str) -> commons.Location:
3551> """
3552> Uses geopy (or other geoloc tool) to get a valid `Location` object from
3553> an address string
3554> """
3555> del address
3556> return commons.Location(lat=22.22,
3557> lng=33.33) # FIXME! Not actually implemented
3558diff -r COPY/utils/comments.py cardway_backend/utils/comments.py
35591,102c1,102
3560< # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
3561< """
3562< Holds the actual implementation for utility method and interfaces for the
3563< user transactions.
3564< """
3565< from enum import Enum
3566< from datetime import datetime
3567< from typing import Dict, Any
3568< from pydantic.error_wrappers import ValidationError
3569< from database.main import get_database, get_db_name
3570< from models import exceptions
3571< from models.comments import Comment, CommentRegistration
3572< from models.commons import CommentId, EventId, UserId
3573< import utils.commons as commons_util
3574< from utils.events import add_comment
3575< db = get_database()
3576< COLLECTION_NAME = "comments"
3577< collection = db[get_db_name()][COLLECTION_NAME]
3578<
3579< async def get_comment_by_id(comment_id: CommentId) -> Comment:
3580< query = await get_default_query(comment_id)
3581< document = collection.find_one(query)
3582< if not document:
3583< message = f"Comment with id {comment_id} not found!"
3584< raise exceptions.ResourceNotFoundDefault(message)
3585< return Comment(**document)
3586<
3587< async def get_default_query(comment_id: CommentId) -> Dict[str, CommentId]:
3588< await commons_util.check_uuid_valid(comment_id)
3589< return {"_id": comment_id}
3590<
3591< async def comment_from_comment_registration_form(
3592< comment_form: CommentRegistration) -> Comment:
3593< """
3594< Top level `from()` that does all of the necessary serverside changes
3595< to tranform an `CommentRegistrationForm` to a valid Comment.
3596<
3597< Raises invalid data exception (422) if it cannot be validated.
3598< """
3599< # validate the comment registration form before working on it any further
3600< await validate_comment_registration_form(comment_form)
3601< comment_dict = comment_form.dict()
3602<
3603< try:
3604< comment_dict.update({"timestamp":datetime.now()})
3605< validated_comment = Comment(**comment_dict)
3606< except ValidationError as e: # pylint: disable=invalid-name
3607< message = f"Invalid data in comment registration form: {e}"
3608< raise exceptions.InvalidDataTypeException(message)
3609< return validated_comment
3610<
3611<
3612< async def validate_comment_registration_form(comment_form: Any) -> None: # pylint: disable=invalid-name
3613< """
3614< Takes in any data type and tries to see if it is a
3615< valid `CommentRegistration` object, raising an exception
3616< if it is invalid. Returns None if valid.
3617< """
3618< message = "Invalid comment registration form data"
3619< if not isinstance(comment_form, CommentRegistration):
3620< raise exceptions.InvalidDataTypeException(message)
3621< try:
3622< # explicit typecasting as validation
3623< CommentRegistration(**comment_form.dict())
3624< except ValidationError as validation_error:
3625< raise exceptions.InvalidDataTypeException(
3626< message) from validation_error
3627<
3628<
3629< async def set_enums_to_string_values(comment_dict: Dict[str, str]) -> None:
3630< """
3631< Modifies the comment dict to have their enums set to strings in-place.
3632< There is definitely a better way to do this but handing it off to a
3633< method at least gives us room to refactor later.
3634< """
3635< for key in comment_dict.keys():
3636< field = comment_dict[key]
3637< if isinstance(field, Enum):
3638< comment_dict[key] = field.value
3639<
3640<
3641<
3642< async def register_comment(form: CommentRegistration) -> CommentId:
3643< valid_comment = await comment_from_comment_registration_form(form)
3644< comment_id = valid_comment.id
3645< comment_dict = valid_comment.dict()
3646< # to get rid of enum jankness
3647< await set_enums_to_string_values(comment_dict)
3648<
3649< # FIXME: the `id` bug shows up once more;
3650< # this is a very temporary fix until we finally squash it in mongo.
3651< await commons_util.fix_dict_id_key_and_value(comment_dict)
3652< collection.insert_one(comment_dict)
3653< return comment_id
3654<
3655<
3656< async def add_liking_user(comment_id: CommentId, user_id: UserId):
3657< collection.update_one({"_id": comment_id},{"$addtoSet":{"liking_users":
3658< user_id}})
3659<
3660< async def remove_liking_user(comment_id: CommentId, user_id: UserId):
3661< collection.update_one({"_id": comment_id},{"$pull":{"liking_users":
3662---
3663> # pylint: disable=no-name-in-module; see https://github.com/samuelcolvin/pydantic/issues/1961
3664> """
3665> Holds the actual implementation for utility method and interfaces for the
3666> user transactions.
3667> """
3668> from enum import Enum
3669> from datetime import datetime
3670> from typing import Dict, Any
3671> from pydantic.error_wrappers import ValidationError
3672> from database.main import get_database, get_db_name
3673> from models import exceptions
3674> from models.comments import Comment, CommentRegistration
3675> from models.commons import CommentId, EventId, UserId
3676> import utils.commons as commons_util
3677> from utils.events import add_comment
3678> db = get_database()
3679> COLLECTION_NAME = "comments"
3680> collection = db[get_db_name()][COLLECTION_NAME]
3681>
3682> async def get_comment_by_id(comment_id: CommentId) -> Comment:
3683> query = await get_default_query(comment_id)
3684> document = collection.find_one(query)
3685> if not document:
3686> message = f"Comment with id {comment_id} not found!"
3687> raise exceptions.ResourceNotFoundDefault(message)
3688> return Comment(**document)
3689>
3690> async def get_default_query(comment_id: CommentId) -> Dict[str, CommentId]:
3691> await commons_util.check_uuid_valid(comment_id)
3692> return {"_id": comment_id}
3693>
3694> async def comment_from_comment_registration_form(
3695> comment_form: CommentRegistration) -> Comment:
3696> """
3697> Top level `from()` that does all of the necessary serverside changes
3698> to tranform an `CommentRegistrationForm` to a valid Comment.
3699>
3700> Raises invalid data exception (422) if it cannot be validated.
3701> """
3702> # validate the comment registration form before working on it any further
3703> await validate_comment_registration_form(comment_form)
3704> comment_dict = comment_form.dict()
3705>
3706> try:
3707> comment_dict.update({"timestamp":datetime.now()})
3708> validated_comment = Comment(**comment_dict)
3709> except ValidationError as e: # pylint: disable=invalid-name
3710> message = f"Invalid data in comment registration form: {e}"
3711> raise exceptions.InvalidDataTypeException(message)
3712> return validated_comment
3713>
3714>
3715> async def validate_comment_registration_form(comment_form: Any) -> None: # pylint: disable=invalid-name
3716> """
3717> Takes in any data type and tries to see if it is a
3718> valid `CommentRegistration` object, raising an exception
3719> if it is invalid. Returns None if valid.
3720> """
3721> message = "Invalid comment registration form data"
3722> if not isinstance(comment_form, CommentRegistration):
3723> raise exceptions.InvalidDataTypeException(message)
3724> try:
3725> # explicit typecasting as validation
3726> CommentRegistration(**comment_form.dict())
3727> except ValidationError as validation_error:
3728> raise exceptions.InvalidDataTypeException(
3729> message) from validation_error
3730>
3731>
3732> async def set_enums_to_string_values(comment_dict: Dict[str, str]) -> None:
3733> """
3734> Modifies the comment dict to have their enums set to strings in-place.
3735> There is definitely a better way to do this but handing it off to a
3736> method at least gives us room to refactor later.
3737> """
3738> for key in comment_dict.keys():
3739> field = comment_dict[key]
3740> if isinstance(field, Enum):
3741> comment_dict[key] = field.value
3742>
3743>
3744>
3745> async def register_comment(form: CommentRegistration) -> CommentId:
3746> valid_comment = await comment_from_comment_registration_form(form)
3747> comment_id = valid_comment.id
3748> comment_dict = valid_comment.dict()
3749> # to get rid of enum jankness
3750> await set_enums_to_string_values(comment_dict)
3751>
3752> # FIXME: the `id` bug shows up once more;
3753> # this is a very temporary fix until we finally squash it in mongo.
3754> await commons_util.fix_dict_id_key_and_value(comment_dict)
3755> collection.insert_one(comment_dict)
3756> return comment_id
3757>
3758>
3759> async def add_liking_user(comment_id: CommentId, user_id: UserId):
3760> collection.update_one({"_id": comment_id},{"$addtoSet":{"liking_users":
3761> user_id}})
3762>
3763> async def remove_liking_user(comment_id: CommentId, user_id: UserId):
3764> collection.update_one({"_id": comment_id},{"$pull":{"liking_users":
3765diff -r COPY/utils/coviddata.py cardway_backend/utils/coviddata.py
37661,98c1,98
3767< # pylint: skip-file
3768< from bs4 import BeautifulSoup
3769< import requests
3770< import csv
3771< from models import CovidData
3772< from database import db_session, engine
3773<
3774< #Compiles a 7 day average of new cases in every county
3775< #Covid levels correspond to the CDC risk levels https://www.cdc.gov/coronavirus/2019-ncov/travelers/how-level-is-determined.html
3776<
3777< CSV_URL = "https://usafactsstatic.blob.core.windows.net/public/data/covid-19/covid_confirmed_usafacts.csv"
3778< states = [
3779< "alabama", "alaska", "arizona", "arkansas", "california", "colorado",
3780< "connecticut", "delaware", "florida", "georgia", "hawaii", "idaho",
3781< "illinois", "indiana", "iowa", "kansas", "kentucky", "louisiana", "maine",
3782< "maryland", "massachusetts", "michigan", "minnesota", "mississippi",
3783< "missouri", "montana", "nebraska", "nevada", "new-hampshire", "new-jersey",
3784< "new-mexico", "new-york", "north-carolina", "north-dakota", "ohio",
3785< "oklahoma", "oregon", "pennsylvania", "rhode-island", "south-carolina",
3786< "south-dakota", "tennessee", "texas", "utah", "vermont", "virginia",
3787< "washington", "west-virginia", "wisconsin", "wyoming"
3788< ]
3789< data = []
3790< output = ""
3791<
3792< with requests.Session() as s:
3793< download = s.get(CSV_URL)
3794< decoded = download.content.decode('utf-8')
3795<
3796< cr = csv.reader(decoded.splitlines(), delimiter=",")
3797< my_list = list(cr)
3798< del my_list[0]
3799< cols = len(my_list[0])
3800< for row in my_list:
3801< s = 0
3802< for i in range(7):
3803< s += int(row[cols - 1 - i]) - int(
3804< row[cols - 2 - i]) #int(row[cols-1-i])
3805< mean = s / 7
3806< print(row[2] + ", " + row[1] + ", " + str(mean))
3807<
3808< covid_level = -1
3809< max_going = 1000000000
3810< max_invited = 1000000000
3811<
3812< if mean <= 6:
3813< covid_level = 1
3814< max_going = 10
3815< max_invited = 10
3816< elif mean <= 10:
3817< covid_level = 2
3818< max_going = 5
3819< max_invited = 5
3820< else:
3821< covid_level = 3
3822< max_going = 0
3823< max_invited = 0
3824< county_row = db_session.query(CovidData).filter(
3825< CovidData.state_name == row[2],
3826< CovidData.county_name == row[1]).first()
3827< if county_row:
3828< county_row.covid_level = covid_level
3829< county_row.max_going = max_going
3830< county_row.max_invited = max_invited
3831<
3832< else:
3833< db_session.add(
3834< CovidData(state_name=row[2],
3835< county_name=row[1],
3836< covid_level=covid_level,
3837< max_going=max_going,
3838< max_invited=max_invited))
3839< db_session.commit()
3840< #f = open("coviddata.txt", "w")
3841< #f.write(output)
3842< #f.close()
3843<
3844< #for state in states:
3845< #r = requests.get('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state))
3846< #soup = BeautifulSoup(r.text, 'html.parser')
3847< #for body in soup.find_all("tbody"):
3848< #for row in body.find_all("tr"):
3849< #data_point = [state, row.th.text.replace(" ", "-").lower()]
3850< #s+=data_point[0] + ": " + data_point[1] + "\n"
3851< #for col in row.find_all("td"):
3852< #data_point.append(float(col.text.replace(',', '')))
3853< #data.append(data_point)
3854< #s+= "state: " + str(data_point[0]) + ", County: " + str(data_point[1]) + ", Known Cases: " + str(data_point[2]) + ", Deaths: " + str(data_point[3]) + ", Known Cases/100k: " + str(data_point[4]) + "\n"
3855<
3856< #for [state, county] in data:
3857< #r = requests.get('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state) + '/county/' + str(county))
3858< #soup = BeautifulSoup(r.text, 'html.parser')
3859< #print('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state) + '/county/' + str(county))
3860< #f = open("coviddata.txt", "w")
3861< #f.write(s)
3862< #f.close()
3863<
3864< #print(*data, sep="\n")
3865---
3866> # pylint: skip-file
3867> from bs4 import BeautifulSoup
3868> import requests
3869> import csv
3870> from models import CovidData
3871> from database import db_session, engine
3872>
3873> #Compiles a 7 day average of new cases in every county
3874> #Covid levels correspond to the CDC risk levels https://www.cdc.gov/coronavirus/2019-ncov/travelers/how-level-is-determined.html
3875>
3876> CSV_URL = "https://usafactsstatic.blob.core.windows.net/public/data/covid-19/covid_confirmed_usafacts.csv"
3877> states = [
3878> "alabama", "alaska", "arizona", "arkansas", "california", "colorado",
3879> "connecticut", "delaware", "florida", "georgia", "hawaii", "idaho",
3880> "illinois", "indiana", "iowa", "kansas", "kentucky", "louisiana", "maine",
3881> "maryland", "massachusetts", "michigan", "minnesota", "mississippi",
3882> "missouri", "montana", "nebraska", "nevada", "new-hampshire", "new-jersey",
3883> "new-mexico", "new-york", "north-carolina", "north-dakota", "ohio",
3884> "oklahoma", "oregon", "pennsylvania", "rhode-island", "south-carolina",
3885> "south-dakota", "tennessee", "texas", "utah", "vermont", "virginia",
3886> "washington", "west-virginia", "wisconsin", "wyoming"
3887> ]
3888> data = []
3889> output = ""
3890>
3891> with requests.Session() as s:
3892> download = s.get(CSV_URL)
3893> decoded = download.content.decode('utf-8')
3894>
3895> cr = csv.reader(decoded.splitlines(), delimiter=",")
3896> my_list = list(cr)
3897> del my_list[0]
3898> cols = len(my_list[0])
3899> for row in my_list:
3900> s = 0
3901> for i in range(7):
3902> s += int(row[cols - 1 - i]) - int(
3903> row[cols - 2 - i]) #int(row[cols-1-i])
3904> mean = s / 7
3905> print(row[2] + ", " + row[1] + ", " + str(mean))
3906>
3907> covid_level = -1
3908> max_going = 1000000000
3909> max_invited = 1000000000
3910>
3911> if mean <= 6:
3912> covid_level = 1
3913> max_going = 10
3914> max_invited = 10
3915> elif mean <= 10:
3916> covid_level = 2
3917> max_going = 5
3918> max_invited = 5
3919> else:
3920> covid_level = 3
3921> max_going = 0
3922> max_invited = 0
3923> county_row = db_session.query(CovidData).filter(
3924> CovidData.state_name == row[2],
3925> CovidData.county_name == row[1]).first()
3926> if county_row:
3927> county_row.covid_level = covid_level
3928> county_row.max_going = max_going
3929> county_row.max_invited = max_invited
3930>
3931> else:
3932> db_session.add(
3933> CovidData(state_name=row[2],
3934> county_name=row[1],
3935> covid_level=covid_level,
3936> max_going=max_going,
3937> max_invited=max_invited))
3938> db_session.commit()
3939> #f = open("coviddata.txt", "w")
3940> #f.write(output)
3941> #f.close()
3942>
3943> #for state in states:
3944> #r = requests.get('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state))
3945> #soup = BeautifulSoup(r.text, 'html.parser')
3946> #for body in soup.find_all("tbody"):
3947> #for row in body.find_all("tr"):
3948> #data_point = [state, row.th.text.replace(" ", "-").lower()]
3949> #s+=data_point[0] + ": " + data_point[1] + "\n"
3950> #for col in row.find_all("td"):
3951> #data_point.append(float(col.text.replace(',', '')))
3952> #data.append(data_point)
3953> #s+= "state: " + str(data_point[0]) + ", County: " + str(data_point[1]) + ", Known Cases: " + str(data_point[2]) + ", Deaths: " + str(data_point[3]) + ", Known Cases/100k: " + str(data_point[4]) + "\n"
3954>
3955> #for [state, county] in data:
3956> #r = requests.get('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state) + '/county/' + str(county))
3957> #soup = BeautifulSoup(r.text, 'html.parser')
3958> #print('https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/state/' + str(state) + '/county/' + str(county))
3959> #f = open("coviddata.txt", "w")
3960> #f.write(s)
3961> #f.close()
3962>
3963> #print(*data, sep="\n")
3964diff -r COPY/utils/events.py cardway_backend/utils/events.py
39651,375c1,375
3966< # pylint: skip-file
3967< """
3968< Holds implementations of the interface for Events and the Events database.
3969< """
3970< from pydantic.error_wrappers import ValidationError
3971< from models.commons import EventId, UserId, Location, EventRejection
3972< import utils.commons as commons_util
3973< from database.main import get_database, get_db_name
3974< from typing import Dict, Any, List, Tuple
3975< from enum import Enum
3976< from datetime import datetime
3977< from models.events import Event, EventRegistration, EventTag
3978< from models import exceptions
3979< from utils.users import get_user_by_id
3980< from utils.geo import get_distance_between_points
3981< from utils.geo import coordinates_lookup
3982<
3983< db = get_database()
3984< COLLECTION_NAME = "events"
3985< collection = db[get_db_name()][COLLECTION_NAME]
3986<
3987<
3988<
3989< async def get_event_by_id(event_id: EventId) -> Event:
3990< query = await get_default_query(event_id)
3991< document = collection.find_one(query)
3992< if not document:
3993< message = f"Event with id {event_id} not found!"
3994< raise exceptions.ResourceNotFoundDefault(message)
3995< return Event(**document)
3996<
3997<
3998< async def register_event(form: EventRegistration) -> EventId:
3999< valid_event = await event_from_event_registration_form(form)
4000< event_id = valid_event.id
4001< event_dict = valid_event.dict()
4002< # to get rid of enum jankness
4003< await set_enums_to_string_values(event_dict)
4004<
4005< # FIXME: the `id` bug shows up once more;
4006< # this is a very temporary fix until we finally squash it in mongo.
4007< await commons_util.fix_dict_id_key_and_value(event_dict)
4008<
4009< collection.insert_one(event_dict)
4010< return event_id
4011<
4012<
4013< async def update_event_by_id(event_id: EventId,
4014< updated_event: Dict[Any, Any]) -> Event:
4015< query = await get_default_query(event_id)
4016< old_event = collection.find_one(query)
4017< if not old_event:
4018< raise Exception(f"Event with id {event_id} not found!")
4019< new_dict = old_event.update(updated_event)
4020< collection.update_one(query, {"$set": new_dict})
4021< return Event(**new_dict)
4022<
4023<
4024< async def get_default_query(event_id: EventId) -> Dict[str, EventId]:
4025< await commons_util.check_uuid_valid(event_id)
4026< return {"_id": event_id}
4027<
4028<
4029< async def check_event_exists(event_id: EventId) -> bool:
4030< await commons_util.check_uuid_valid(event_id)
4031< try:
4032< await get_event_by_id(event_id)
4033< return True
4034< except exceptions.ResourceNotFoundDefault:
4035< return False
4036<
4037<
4038< async def event_from_event_registration_form(
4039< event_form: EventRegistration) -> Event:
4040< """
4041< Top level `from()` that does all of the necessary serverside changes
4042< to tranform an `EventRegistrationForm` to a valid Event.
4043<
4044< Raises invalid data exception (422) if it cannot be validated.
4045< """
4046< # validate the event registration form before working on it any further
4047< await validate_event_registration_form(event_form)
4048< event_dict = event_form.dict()
4049< await set_event_dict_locations(event_dict)
4050< try:
4051< validated_event = Event(**event_dict)
4052< except ValidationError as e: # pylint: disable=invalid-name
4053< message = f"Invalid data in event registration form: {e}"
4054< raise exceptions.InvalidDataTypeException(message)
4055< return validated_event
4056<
4057<
4058< async def validate_event_registration_form(event_form: Any) -> None: # pylint: disable=invalid-name
4059< """
4060< Takes in any data type and tries to see if it is a valid `EventRegistration`
4061< object, raising an exception if it is invalid.
4062< Returns None if valid.
4063< """
4064< message = "Invalid event registration form data"
4065< if not isinstance(event_form, EventRegistration):
4066< raise exceptions.InvalidDataTypeException(message)
4067< try:
4068< # explicit typecasting as validation
4069< EventRegistration(**event_form.dict())
4070< except ValidationError as validation_error:
4071< raise exceptions.InvalidDataTypeException(
4072< message) from validation_error
4073<
4074<
4075< async def set_enums_to_string_values(event_dict: Dict[str, str]) -> None:
4076< """
4077< Modifies the event dict to have their enums set to strings in-place.
4078< There is definitely a better way to do this but handing it off to a
4079< method at least gives us room to refactor later.
4080< """
4081< for key in event_dict.keys():
4082< field = event_dict[key]
4083< if isinstance(field, Enum):
4084< event_dict[key] = field.value
4085<
4086<
4087< async def set_event_dict_locations(event_dict: Dict[str, str]) -> None:
4088< """
4089< Sets all of the location coordinates for the event dict that the
4090< client _doesn't_ set.
4091< """
4092< address = event_dict["location_name"]
4093< if "location_coords" not in event_dict:
4094< event_dict["location_coords"] = await get_location_cords_from_address(
4095< address)
4096<
4097<
4098< async def get_location_cords_from_address(address: str) -> Location:
4099< """
4100< Uses geopy (or other geoloc tool) to get a valid `Location` object from
4101< an address string
4102< """
4103< coordinates = coordinates_lookup(address)
4104< return Location(coordinates['lat'], coordinates['lng'])
4105<
4106<
4107< async def check_user_invited_to_event(user_id: UserId,
4108< event_id: EventId) -> bool:
4109< #TODO: error handling
4110< event = await get_event_by_id(event_id)
4111< return user_id in event.invited_users
4112<
4113<
4114< async def get_users_invited_to_event(event_id: EventId) -> List[UserId]:
4115< #TODO: figure out a more concise function name and error handling
4116< event = await get_event_by_id(event_id)
4117< return event.invited_users
4118<
4119<
4120< def get_db_events_within_radius(tag, center_lat, center_lng, radius, user_id):
4121< raise Exception("Unimplemented!")
4122<
4123<
4124< # async def get_lat_long_tuple_from_event(event: Event) -> Tuple[float, float]:
4125< # """
4126< # Simple function to abstract the actual object field access from the caller.
4127< # """
4128< # event_location_lat = event.location_coords.lat
4129< # event_location_lng = event.location_coords.lng
4130< # return (event_location_lat, event_location_lng)
4131<
4132<
4133< # pylint: disable=invalid-name
4134< async def get_distance_between_user_and_event(user_location: Location,
4135< event: Event) -> float:
4136< """
4137< Given a user's location coords and an event, returns the disctance
4138< between the two.
4139<
4140< Guaranteed to be > 0.
4141< """
4142< event_location = event.location_coords
4143< user_distance_from_event = get_distance_between_points(
4144< event_location, user_location)
4145< return max(.00001, user_distance_from_event)
4146<
4147<
4148< async def get_events_in_radius_query(user_location: Location, radius):
4149< """
4150< Returns a query for getting all or location cards events within [radius]
4151< of [user_location]
4152< """
4153< user_lat = user_location.lat
4154< user_lng = user_location.lng
4155< query = {
4156< "location_coords": {
4157< "$near": {
4158< "$geometry": {
4159< "type": "Point",
4160< "coordinates": [user_lat, user_lng]
4161< },
4162< "$minDistance": 0,
4163< "$maxDistance": radius
4164< }
4165< }
4166< }
4167< return(query)
4168<
4169< async def get_filter_locations_query():
4170< """
4171< Returns a query for getting all location cards
4172< """
4173< query = {"tag":{"$ne":EventTag.LOCATION.value}}
4174< return query
4175<
4176< async def get_filter_rejected_event_query(user_id: UserId):
4177< """
4178< Returns a query for getting all events *not* rejected by
4179< a user
4180< """
4181< user = await get_user_by_id(user_id)
4182< query = {"_id":{"$nin":user.rejected_events}}
4183< return query
4184<
4185< async def get_rejected_location_ids(user_id: UserId):
4186< """
4187< Returns the ids of all *locations* rejected by a user
4188< """
4189< user = await get_user_by_id(user_id)
4190< location_ids = [x.rejected_event_id for x in user.rejected_locations]
4191<
4192< async def get_filter_rejected_location_query(user_id: UserId):
4193< """
4194< Returns a query for getting all locations *not* rejected by
4195< a user
4196< """
4197< user = await get_user_by_id(user_id)
4198< query = {"_id":{"$nin": get_rejected_location_ids(user_id)}}
4199<
4200< async def get_filter_all_rejections_query(user_id: UserId):
4201< """
4202< Returns a query for getting all events and locations *not*
4203< rejected by a user
4204< """
4205< query = {"$and": [get_filter_rejected_event_query(user_id),
4206< get_filter_rejected_location_query(user_id)]}
4207< return query
4208<
4209< async def get_events_query(user_id: UserId, user_location: Location,
4210< radius: float):
4211< """
4212< Returns a query for getting all non-rejected events and locations
4213< within a radius of user's location
4214< """
4215< radius_query = await get_events_in_radius_query(user_location, radius)
4216< filter_rejections_query = await get_filter_all_rejections_query(user_id)
4217< query = {"$and": [radius_query, filter_rejections_query]}
4218< return query
4219<
4220<
4221< async def get_filter_tag_query(tag:EventTag):
4222< query = {"tag": tag.value}
4223< return query
4224<
4225<
4226< async def user_can_view(user_id, event_id):
4227< """
4228< Checks whether a user can view an event under the event's
4229< privacy settings
4230< """
4231< event = get_event_by_id(event_id)
4232< if event.privacy == EventPrivacy.PUBLIC:
4233< return True
4234< else:
4235< return False
4236<
4237< # NOTE: this is a very important function.
4238< # Talk about implementation in design meeting
4239< #Returns list of events, NOT event ids
4240< async def discover_events(user_id: UserId,
4241< user_location: Location,
4242< radius: float,
4243< tag: EventTag = None,
4244< location: bool = True) -> List[EventId]:
4245< """
4246< Given a user ID and their location info, returns list
4247< of all discovered events around them, sorted according to
4248< the relative likelyhood of a user going to them.
4249< """
4250< def score(event):
4251< event_score = await get_total_score_for_event(user_location,
4252< event)
4253< return event_score
4254< def is_viewable(event):
4255< viewable = await user_can_view(user_id, event.id)
4256< return viewable
4257<
4258< events = []
4259< queries = []
4260< events_query = await get_events_query(user_id,user_location, radius)
4261< queries.append(events_query)
4262< if tag:
4263< filter_tag_query = get_filter_tag_query(tag)
4264< queries.append(filter_tag_query)
4265< if not location:
4266< location_query = await get_filter_locations_query()
4267< queries.append(location_query)
4268< query = {"$and": queries}
4269<
4270< events = db.collection.find(query)
4271< events = filter(is_viewable, events)
4272< events.sort(True,score)
4273< return events
4274<
4275<
4276< async def get_total_score_for_event(user_location, event: Event) -> float:
4277< """
4278< Does some arithmetic to generate total score for an event, factoring in
4279< distance
4280< """
4281< max_random = 10
4282< relevancy_score_for_user = await relevancy_score(user_id, event)
4283<
4284< return (relevancy_score_for_user * (max_random + random.random()) /
4285< get_distance_between_user_and_event(user_location, event))
4286<
4287<
4288< async def get_interest_in_tag(user, tag):
4289< """
4290< Counts how many events in a tag the user is interested in
4291< """
4292< num_interested = collection.count({
4293< "$and": [{
4294< "_id": {
4295< "$in": user.interested_event_ids
4296< }
4297< }, {
4298< "tag": event.tag
4299< }]
4300< })
4301<
4302< return num_interested
4303<
4304< async def get_going_in_tag(user, tag):
4305< """
4306< Counts how many events in a tag the user has declared
4307< going ot
4308< """
4309< num_going = collection.count(
4310< {"$and": [{
4311< "_id": {
4312< "$in": user.going_event_ids
4313< }
4314< }, {
4315< "tag": event.tag
4316< }]
4317< })
4318<
4319< return num_going
4320<
4321< async def relevancy_score(user_id: UserId, event: Event) -> float:
4322< """
4323< Gives a relative score of how likely a user is to like an event.
4324< Scores are always at least 1.
4325< """
4326< user = await get_user_by_id(user_id)
4327< interest_coeff = 1
4328< interest_exp = 1
4329< going_coeff = 2
4330< going_exp = 2
4331< user_interest = await get_interest_in_tag(user, event.tag)
4332< user_going = await get_going_in_tag(user, event.tag)
4333<
4334< interest_score = interest_coeff * (user_interest**interest_exp)
4335< going_score = going_coeff * (going_score**going_exp)
4336<
4337< return max(1,interest_score + going_score)
4338<
4339< async def add_comment(event_id, comment_id):
4340< collection.update_one({"_id": event_id},{"$addtoSet":{"comments":
4341---
4342> # pylint: skip-file
4343> """
4344> Holds implementations of the interface for Events and the Events database.
4345> """
4346> from pydantic.error_wrappers import ValidationError
4347> from models.commons import EventId, UserId, Location, EventRejection
4348> import utils.commons as commons_util
4349> from database.main import get_database, get_db_name
4350> from typing import Dict, Any, List, Tuple
4351> from enum import Enum
4352> from datetime import datetime
4353> from models.events import Event, EventRegistration, EventTag
4354> from models import exceptions
4355> from utils.users import get_user_by_id
4356> from utils.geo import get_distance_between_points
4357> from utils.geo import coordinates_lookup
4358>
4359> db = get_database()
4360> COLLECTION_NAME = "events"
4361> collection = db[get_db_name()][COLLECTION_NAME]
4362>
4363>
4364>
4365> async def get_event_by_id(event_id: EventId) -> Event:
4366> query = await get_default_query(event_id)
4367> document = collection.find_one(query)
4368> if not document:
4369> message = f"Event with id {event_id} not found!"
4370> raise exceptions.ResourceNotFoundDefault(message)
4371> return Event(**document)
4372>
4373>
4374> async def register_event(form: EventRegistration) -> EventId:
4375> valid_event = await event_from_event_registration_form(form)
4376> event_id = valid_event.id
4377> event_dict = valid_event.dict()
4378> # to get rid of enum jankness
4379> await set_enums_to_string_values(event_dict)
4380>
4381> # FIXME: the `id` bug shows up once more;
4382> # this is a very temporary fix until we finally squash it in mongo.
4383> await commons_util.fix_dict_id_key_and_value(event_dict)
4384>
4385> collection.insert_one(event_dict)
4386> return event_id
4387>
4388>
4389> async def update_event_by_id(event_id: EventId,
4390> updated_event: Dict[Any, Any]) -> Event:
4391> query = await get_default_query(event_id)
4392> old_event = collection.find_one(query)
4393> if not old_event:
4394> raise Exception(f"Event with id {event_id} not found!")
4395> new_dict = old_event.update(updated_event)
4396> collection.update_one(query, {"$set": new_dict})
4397> return Event(**new_dict)
4398>
4399>
4400> async def get_default_query(event_id: EventId) -> Dict[str, EventId]:
4401> await commons_util.check_uuid_valid(event_id)
4402> return {"_id": event_id}
4403>
4404>
4405> async def check_event_exists(event_id: EventId) -> bool:
4406> await commons_util.check_uuid_valid(event_id)
4407> try:
4408> await get_event_by_id(event_id)
4409> return True
4410> except exceptions.ResourceNotFoundDefault:
4411> return False
4412>
4413>
4414> async def event_from_event_registration_form(
4415> event_form: EventRegistration) -> Event:
4416> """
4417> Top level `from()` that does all of the necessary serverside changes
4418> to tranform an `EventRegistrationForm` to a valid Event.
4419>
4420> Raises invalid data exception (422) if it cannot be validated.
4421> """
4422> # validate the event registration form before working on it any further
4423> await validate_event_registration_form(event_form)
4424> event_dict = event_form.dict()
4425> await set_event_dict_locations(event_dict)
4426> try:
4427> validated_event = Event(**event_dict)
4428> except ValidationError as e: # pylint: disable=invalid-name
4429> message = f"Invalid data in event registration form: {e}"
4430> raise exceptions.InvalidDataTypeException(message)
4431> return validated_event
4432>
4433>
4434> async def validate_event_registration_form(event_form: Any) -> None: # pylint: disable=invalid-name
4435> """
4436> Takes in any data type and tries to see if it is a valid `EventRegistration`
4437> object, raising an exception if it is invalid.
4438> Returns None if valid.
4439> """
4440> message = "Invalid event registration form data"
4441> if not isinstance(event_form, EventRegistration):
4442> raise exceptions.InvalidDataTypeException(message)
4443> try:
4444> # explicit typecasting as validation
4445> EventRegistration(**event_form.dict())
4446> except ValidationError as validation_error:
4447> raise exceptions.InvalidDataTypeException(
4448> message) from validation_error
4449>
4450>
4451> async def set_enums_to_string_values(event_dict: Dict[str, str]) -> None:
4452> """
4453> Modifies the event dict to have their enums set to strings in-place.
4454> There is definitely a better way to do this but handing it off to a
4455> method at least gives us room to refactor later.
4456> """
4457> for key in event_dict.keys():
4458> field = event_dict[key]
4459> if isinstance(field, Enum):
4460> event_dict[key] = field.value
4461>
4462>
4463> async def set_event_dict_locations(event_dict: Dict[str, str]) -> None:
4464> """
4465> Sets all of the location coordinates for the event dict that the
4466> client _doesn't_ set.
4467> """
4468> address = event_dict["location_name"]
4469> if "location_coords" not in event_dict:
4470> event_dict["location_coords"] = await get_location_cords_from_address(
4471> address)
4472>
4473>
4474> async def get_location_cords_from_address(address: str) -> Location:
4475> """
4476> Uses geopy (or other geoloc tool) to get a valid `Location` object from
4477> an address string
4478> """
4479> coordinates = coordinates_lookup(address)
4480> return Location(coordinates['lat'], coordinates['lng'])
4481>
4482>
4483> async def check_user_invited_to_event(user_id: UserId,
4484> event_id: EventId) -> bool:
4485> #TODO: error handling
4486> event = await get_event_by_id(event_id)
4487> return user_id in event.invited_users
4488>
4489>
4490> async def get_users_invited_to_event(event_id: EventId) -> List[UserId]:
4491> #TODO: figure out a more concise function name and error handling
4492> event = await get_event_by_id(event_id)
4493> return event.invited_users
4494>
4495>
4496> def get_db_events_within_radius(tag, center_lat, center_lng, radius, user_id):
4497> raise Exception("Unimplemented!")
4498>
4499>
4500> # async def get_lat_long_tuple_from_event(event: Event) -> Tuple[float, float]:
4501> # """
4502> # Simple function to abstract the actual object field access from the caller.
4503> # """
4504> # event_location_lat = event.location_coords.lat
4505> # event_location_lng = event.location_coords.lng
4506> # return (event_location_lat, event_location_lng)
4507>
4508>
4509> # pylint: disable=invalid-name
4510> async def get_distance_between_user_and_event(user_location: Location,
4511> event: Event) -> float:
4512> """
4513> Given a user's location coords and an event, returns the disctance
4514> between the two.
4515>
4516> Guaranteed to be > 0.
4517> """
4518> event_location = event.location_coords
4519> user_distance_from_event = get_distance_between_points(
4520> event_location, user_location)
4521> return max(.00001, user_distance_from_event)
4522>
4523>
4524> async def get_events_in_radius_query(user_location: Location, radius):
4525> """
4526> Returns a query for getting all or location cards events within [radius]
4527> of [user_location]
4528> """
4529> user_lat = user_location.lat
4530> user_lng = user_location.lng
4531> query = {
4532> "location_coords": {
4533> "$near": {
4534> "$geometry": {
4535> "type": "Point",
4536> "coordinates": [user_lat, user_lng]
4537> },
4538> "$minDistance": 0,
4539> "$maxDistance": radius
4540> }
4541> }
4542> }
4543> return(query)
4544>
4545> async def get_filter_locations_query():
4546> """
4547> Returns a query for getting all location cards
4548> """
4549> query = {"tag":{"$ne":EventTag.LOCATION.value}}
4550> return query
4551>
4552> async def get_filter_rejected_event_query(user_id: UserId):
4553> """
4554> Returns a query for getting all events *not* rejected by
4555> a user
4556> """
4557> user = await get_user_by_id(user_id)
4558> query = {"_id":{"$nin":user.rejected_events}}
4559> return query
4560>
4561> async def get_rejected_location_ids(user_id: UserId):
4562> """
4563> Returns the ids of all *locations* rejected by a user
4564> """
4565> user = await get_user_by_id(user_id)
4566> location_ids = [x.rejected_event_id for x in user.rejected_locations]
4567>
4568> async def get_filter_rejected_location_query(user_id: UserId):
4569> """
4570> Returns a query for getting all locations *not* rejected by
4571> a user
4572> """
4573> user = await get_user_by_id(user_id)
4574> query = {"_id":{"$nin": get_rejected_location_ids(user_id)}}
4575>
4576> async def get_filter_all_rejections_query(user_id: UserId):
4577> """
4578> Returns a query for getting all events and locations *not*
4579> rejected by a user
4580> """
4581> query = {"$and": [get_filter_rejected_event_query(user_id),
4582> get_filter_rejected_location_query(user_id)]}
4583> return query
4584>
4585> async def get_events_query(user_id: UserId, user_location: Location,
4586> radius: float):
4587> """
4588> Returns a query for getting all non-rejected events and locations
4589> within a radius of user's location
4590> """
4591> radius_query = await get_events_in_radius_query(user_location, radius)
4592> filter_rejections_query = await get_filter_all_rejections_query(user_id)
4593> query = {"$and": [radius_query, filter_rejections_query]}
4594> return query
4595>
4596>
4597> async def get_filter_tag_query(tag:EventTag):
4598> query = {"tag": tag.value}
4599> return query
4600>
4601>
4602> async def user_can_view(user_id, event_id):
4603> """
4604> Checks whether a user can view an event under the event's
4605> privacy settings
4606> """
4607> event = get_event_by_id(event_id)
4608> if event.privacy == EventPrivacy.PUBLIC:
4609> return True
4610> else:
4611> return False
4612>
4613> # NOTE: this is a very important function.
4614> # Talk about implementation in design meeting
4615> #Returns list of events, NOT event ids
4616> async def discover_events(user_id: UserId,
4617> user_location: Location,
4618> radius: float,
4619> tag: EventTag = None,
4620> location: bool = True) -> List[EventId]:
4621> """
4622> Given a user ID and their location info, returns list
4623> of all discovered events around them, sorted according to
4624> the relative likelyhood of a user going to them.
4625> """
4626> def score(event):
4627> event_score = await get_total_score_for_event(user_location,
4628> event)
4629> return event_score
4630> def is_viewable(event):
4631> viewable = await user_can_view(user_id, event.id)
4632> return viewable
4633>
4634> events = []
4635> queries = []
4636> events_query = await get_events_query(user_id,user_location, radius)
4637> queries.append(events_query)
4638> if tag:
4639> filter_tag_query = get_filter_tag_query(tag)
4640> queries.append(filter_tag_query)
4641> if not location:
4642> location_query = await get_filter_locations_query()
4643> queries.append(location_query)
4644> query = {"$and": queries}
4645>
4646> events = db.collection.find(query)
4647> events = filter(is_viewable, events)
4648> events.sort(True,score)
4649> return events
4650>
4651>
4652> async def get_total_score_for_event(user_location, event: Event) -> float:
4653> """
4654> Does some arithmetic to generate total score for an event, factoring in
4655> distance
4656> """
4657> max_random = 10
4658> relevancy_score_for_user = await relevancy_score(user_id, event)
4659>
4660> return (relevancy_score_for_user * (max_random + random.random()) /
4661> get_distance_between_user_and_event(user_location, event))
4662>
4663>
4664> async def get_interest_in_tag(user, tag):
4665> """
4666> Counts how many events in a tag the user is interested in
4667> """
4668> num_interested = collection.count({
4669> "$and": [{
4670> "_id": {
4671> "$in": user.interested_event_ids
4672> }
4673> }, {
4674> "tag": event.tag
4675> }]
4676> })
4677>
4678> return num_interested
4679>
4680> async def get_going_in_tag(user, tag):
4681> """
4682> Counts how many events in a tag the user has declared
4683> going ot
4684> """
4685> num_going = collection.count(
4686> {"$and": [{
4687> "_id": {
4688> "$in": user.going_event_ids
4689> }
4690> }, {
4691> "tag": event.tag
4692> }]
4693> })
4694>
4695> return num_going
4696>
4697> async def relevancy_score(user_id: UserId, event: Event) -> float:
4698> """
4699> Gives a relative score of how likely a user is to like an event.
4700> Scores are always at least 1.
4701> """
4702> user = await get_user_by_id(user_id)
4703> interest_coeff = 1
4704> interest_exp = 1
4705> going_coeff = 2
4706> going_exp = 2
4707> user_interest = await get_interest_in_tag(user, event.tag)
4708> user_going = await get_going_in_tag(user, event.tag)
4709>
4710> interest_score = interest_coeff * (user_interest**interest_exp)
4711> going_score = going_coeff * (going_score**going_exp)
4712>
4713> return max(1,interest_score + going_score)
4714>
4715> async def add_comment(event_id, comment_id):
4716> collection.update_one({"_id": event_id},{"$addtoSet":{"comments":
4717diff -r COPY/utils/geo.py cardway_backend/utils/geo.py
47181d0
4719< # pylint: skip-file
47203d1
4721< from datetime import datetime
47225c3
4723<
4724---
4725> import math
472618c16
4727< geocode_lookup_json = reverse_geocode(latitude, longitude)[0]
4728---
4729> geocode_lookup_json = gmaps.reverse_geocode(latitude, longitude)[0]
473046a45
4731>
4732diff -r COPY/utils/posts.py cardway_backend/utils/posts.py
47331,41c1,41
4734< """
4735< Will (eventually) hold the code that deals with posts either from users,
4736< or from business entities, as well as maybe other kinds.
4737< Insofar it is very much dead code and the implementation
4738< date is not on the horizon.
4739< """
4740< from models import posts as models
4741< from models import commons
4742<
4743<
4744< def register_post(post: models.Post) -> commons.PostId:
4745< raise Exception("Unimplemented!")
4746<
4747<
4748< # FIXME: make a better algorithm for post recency
4749< def post_recency(post_id: commons.PostId) -> float:
4750< # time_posted = target_post["timestamp"]
4751< # time_now = time.time()
4752< # time_elapsed = time_now - time_posted
4753< # hours_elapsed = time_elapsed * 1.0 / 3600
4754< # recency = 0.0
4755< # if hours_elapsed <= 3.0:
4756< # recency = .8
4757< # elif hours_elapsed <= 12.0:
4758< # recency = .5
4759< # elif hours_elapsed <= 36.0:
4760< # recency = .3
4761< # else:
4762< # recency = .1
4763< # return recency
4764< raise Exception("Unimplemented!")
4765<
4766<
4767< def check_post_exists(post_id: commons.PostId) -> bool:
4768< raise Exception("Unimplemented!")
4769<
4770<
4771< async def create_post(user_id: commons.UserId,
4772< post: models.Post) -> commons.PostId:
4773< del post, user_id
4774< raise Exception("Unimplemented!")
4775---
4776> """
4777> Will (eventually) hold the code that deals with posts either from users,
4778> or from business entities, as well as maybe other kinds.
4779> Insofar it is very much dead code and the implementation
4780> date is not on the horizon.
4781> """
4782> from models import posts as models
4783> from models import commons
4784>
4785>
4786> def register_post(post: models.Post) -> commons.PostId:
4787> raise Exception("Unimplemented!")
4788>
4789>
4790> # FIXME: make a better algorithm for post recency
4791> def post_recency(post_id: commons.PostId) -> float:
4792> # time_posted = target_post["timestamp"]
4793> # time_now = time.time()
4794> # time_elapsed = time_now - time_posted
4795> # hours_elapsed = time_elapsed * 1.0 / 3600
4796> # recency = 0.0
4797> # if hours_elapsed <= 3.0:
4798> # recency = .8
4799> # elif hours_elapsed <= 12.0:
4800> # recency = .5
4801> # elif hours_elapsed <= 36.0:
4802> # recency = .3
4803> # else:
4804> # recency = .1
4805> # return recency
4806> raise Exception("Unimplemented!")
4807>
4808>
4809> def check_post_exists(post_id: commons.PostId) -> bool:
4810> raise Exception("Unimplemented!")
4811>
4812>
4813> async def create_post(user_id: commons.UserId,
4814> post: models.Post) -> commons.PostId:
4815> del post, user_id
4816> raise Exception("Unimplemented!")
4817diff -r COPY/utils/security.py cardway_backend/utils/security.py
48181,44c1,44
4819< # pylint: skip-file
4820< from models import User, db_session as sesh
4821< import util
4822< from werkzeug.security import generate_password_hash, check_password_hash
4823< from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
4824< method = 'pbkdf2:sha256:100000'
4825<
4826<
4827< def login(sesh, username, password):
4828< try:
4829< pass_hash = sesh.query(
4830< User.pass_hash_salt).filter(User.username == username).one()
4831< except MultipleResultsFound as e:
4832< # Log that multiple results were found, shouldn't have happened.
4833< pass_hash = sesh.query(
4834< User.pass_hash_salt).filter(User.username == username).first()
4835< except NoResultFound as e:
4836< # User was not found/does not exist
4837< return
4838< # TODO: Grab user pass_hash
4839<
4840< return check_password_hash(method + pass_hash, password)
4841<
4842<
4843< def register(sess, username, password, first_name, last_name, phone,
4844< street_address, city, state, zipcode, country, email, birthday,
4845< company):
4846< result = generate_password_hash(password, method, 16)
4847< result = result[result.index('$'):]
4848< user = models.User(username=username,
4849< pass_hash=pass_hash,
4850< pass_salt=pass_salt,
4851< first_name=first_name,
4852< last_name=last_name,
4853< phone=phone,
4854< street_address=street_address,
4855< city=city,
4856< state=state,
4857< zipcode=zipcode,
4858< country=country,
4859< email=email,
4860< birthday=birthday,
4861< company=company)
4862< return True
4863---
4864> # pylint: skip-file
4865> from models import User, db_session as sesh
4866> import util
4867> from werkzeug.security import generate_password_hash, check_password_hash
4868> from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
4869> method = 'pbkdf2:sha256:100000'
4870>
4871>
4872> def login(sesh, username, password):
4873> try:
4874> pass_hash = sesh.query(
4875> User.pass_hash_salt).filter(User.username == username).one()
4876> except MultipleResultsFound as e:
4877> # Log that multiple results were found, shouldn't have happened.
4878> pass_hash = sesh.query(
4879> User.pass_hash_salt).filter(User.username == username).first()
4880> except NoResultFound as e:
4881> # User was not found/does not exist
4882> return
4883> # TODO: Grab user pass_hash
4884>
4885> return check_password_hash(method + pass_hash, password)
4886>
4887>
4888> def register(sess, username, password, first_name, last_name, phone,
4889> street_address, city, state, zipcode, country, email, birthday,
4890> company):
4891> result = generate_password_hash(password, method, 16)
4892> result = result[result.index('$'):]
4893> user = models.User(username=username,
4894> pass_hash=pass_hash,
4895> pass_salt=pass_salt,
4896> first_name=first_name,
4897> last_name=last_name,
4898> phone=phone,
4899> street_address=street_address,
4900> city=city,
4901> state=state,
4902> zipcode=zipcode,
4903> country=country,
4904> email=email,
4905> birthday=birthday,
4906> company=company)
4907> return True
4908diff -r COPY/utils/users.py cardway_backend/utils/users.py
4909115,118c115,121
4910< async def get_user_id_from_identifier(
4911< identifier: models.UserIdentifier) -> commons.UserId:
4912< """
4913< Given an identifier, returns the user ID of user being identifier.
4914---
4915> # # NOTE: this might be better suited (probably) in `events.py`
4916> # # however, some invite handling might be useful here as well.
4917> # async def invite_user_to_event(inviter_user_id,
4918> # other_user_id,
4919> # shared_event_id,
4920> # creation_invite=False):
4921> # raise Exception("Unimplemented!")
4922175,180c178,180
4923< async def get_user_by_id(user_id: commons.UserId) -> models.User:
4924< query = await get_default_query(user_id)
4925< document = collection.find_one(query)
4926< if not document:
4927< raise exceptions.UserNotFoundException
4928< return models.User(**document)
4929---
4930> async def add_interested_event(user_id, event_id):
4931> collection.update_one({"_id": user_id},{"$addtoSet":{"interested_event_ids":
4932> event_id}})
4933187a188
4934> <<<<<<< HEAD
4935189a191,193
4936> <<<<<<< HEAD
4937> =======
4938> =======
4939298a303
4940> >>>>>>> 4b320895c696d11490d1e42e81d801b1343f49b1
4941313a319
4942> >>>>>>> 0318126defc19336ee1e30f96d89fb329e18e665
4943316,317c322,327
4944< async def like_comment(user_id: UserId, comment_id: CommentId):
4945< await add_liking_user(comment_id, user_id)
4946---
4947> async def check_user_exists(user_id: commons.UserId) -> bool:
4948> """
4949> Returns True if user with matching ID exists in databse, else False.
4950> """
4951> user = await get_user_by_id(user_id)
4952> return user is not None
4953318a329,336
4954> <<<<<<< HEAD
4955>
4956> async def check_user_data_unique(
4957> reg_form: models.UserRegistrationForm) -> None:
4958> """
4959> Checks that the user registration form contains only unique data
4960> on identifier fields.
4961> =======
4962347a366
4963> >>>>>>> 0318126defc19336ee1e30f96d89fb329e18e665
4964348a368,388
4965> <<<<<<< HEAD
4966> Raises an exception if that isn't true, else just returns.
4967> """
4968> username = reg_form.username
4969> email = reg_form.email
4970> query = {"$or": [{"username": username}, {"email": email}]}
4971> user_document = collection.find_one(query)
4972> if user_document:
4973> if user_document["username"] == username:
4974> message = "Username already in use"
4975> else:
4976> message = "Email already in use"
4977> raise exceptions.DuplicateUserError(detail=message)
4978>
4979>
4980> async def get_created_events(user_id: commons.UserId) -> List[commons.EventId]:
4981> query = await get_default_query(user_id)
4982> query_filter = {"_id": 0, "created_event_ids": 1}
4983> event_ids = collection.find_one(query, query_filter)
4984> return event_ids
4985> =======
4986356a397
4987> >>>>>>> 4b320895c696d11490d1e42e81d801b1343f49b1
4988diff -r COPY/utils/util.py cardway_backend/utils/util.py
49891,47c1,47
4990< # pylint: skip-file
4991< import os, json, sys
4992<
4993<
4994< def _init_config():
4995< init = {
4996< 'DEBUG': True,
4997< 'SQLALCHEMY_TRACK_MODIFICATIONS': False,
4998< 'SQLALCHEMY_DATABASE_URI': 'sqlite:///sqlite_tables.db',
4999< 'SECRET_KEY': '',
5000< }
5001< f = open('config.json', 'w')
5002< f.write(json.dumps(init, sort_keys=True, indent=4))
5003< f.close()
5004< del f
5005< print(
5006< 'Initial config.json has been generated. Please configure this server then restart.'
5007< )
5008< sys.exit(0)
5009<
5010<
5011< def read_config():
5012< f = open('config.json', 'r')
5013< config = json.loads(f.read())
5014< f.close()
5015< del f
5016< return config
5017<
5018<
5019< # Open or initialize config into dictionary
5020< def init_config(path='config.json'):
5021< if not os.path.exists(path):
5022< _init_config()
5023< return read_config()
5024<
5025<
5026< def retrieve_conf(varname, config):
5027< env_ = os.getenv(varname, None)
5028< return env_ if env_ != None else config[varname]
5029<
5030<
5031< def successful(status_code):
5032< return 200 <= status_code < 300
5033<
5034<
5035< def to_dict(x):
5036< return x.__dict__
5037---
5038> # pylint: skip-file
5039> import os, json, sys
5040>
5041>
5042> def _init_config():
5043> init = {
5044> 'DEBUG': True,
5045> 'SQLALCHEMY_TRACK_MODIFICATIONS': False,
5046> 'SQLALCHEMY_DATABASE_URI': 'sqlite:///sqlite_tables.db',
5047> 'SECRET_KEY': '',
5048> }
5049> f = open('config.json', 'w')
5050> f.write(json.dumps(init, sort_keys=True, indent=4))
5051> f.close()
5052> del f
5053> print(
5054> 'Initial config.json has been generated. Please configure this server then restart.'
5055> )
5056> sys.exit(0)
5057>
5058>
5059> def read_config():
5060> f = open('config.json', 'r')
5061> config = json.loads(f.read())
5062> f.close()
5063> del f
5064> return config
5065>
5066>
5067> # Open or initialize config into dictionary
5068> def init_config(path='config.json'):
5069> if not os.path.exists(path):
5070> _init_config()
5071> return read_config()
5072>
5073>
5074> def retrieve_conf(varname, config):
5075> env_ = os.getenv(varname, None)
5076> return env_ if env_ != None else config[varname]
5077>
5078>
5079> def successful(status_code):
5080> return 200 <= status_code < 300
5081>
5082>
5083> def to_dict(x):
5084> return x.__dict__
5085