• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gcivil-nyu-org / team1-wed-fall25 / 93

30 Oct 2025 03:50AM UTC coverage: 84.321% (+9.3%) from 75.035%
93

push

travis-pro

web-flow
Merge pull request #90 from gcivil-nyu-org/itineraries-nived

PR for Itineraries

167 of 201 new or added lines in 7 files covered. (83.08%)

6 existing lines in 2 files now uncovered.

1366 of 1620 relevant lines covered (84.32%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.83
/events/selectors.py
1
from django.db.models import Q
1✔
2
from django.contrib.auth import get_user_model
1✔
3
from loc_detail.models import PublicArt
1✔
4

5
User = get_user_model()
1✔
6

7

8
def search_locations(term, limit=10):
1✔
9
    """Search for art locations by title, artist, or location name"""
10
    return PublicArt.objects.filter(
1✔
11
        Q(title__icontains=term)
12
        | Q(artist_name__icontains=term)
13
        | Q(location__icontains=term),
14
        latitude__isnull=False,
15
        longitude__isnull=False,
16
    ).values("id", "title", "artist_name", "latitude", "longitude")[:limit]
17

18

19
def search_users(term, limit=10):
1✔
20
    """Search for users by username or email"""
21
    return User.objects.filter(
1✔
22
        Q(username__icontains=term) | Q(email__icontains=term)
23
    ).values("id", "username")[:limit]
24

25

26
def public_event_pins():
1✔
27
    """Get public event pins for map display"""
28
    from .models import Event
1✔
29
    from .enums import EventVisibility
1✔
30

31
    return (
1✔
32
        Event.objects.filter(
33
            visibility__in=[EventVisibility.PUBLIC_OPEN, EventVisibility.PUBLIC_INVITE],
34
            is_deleted=False,
35
        )
36
        .select_related("start_location")
37
        .values(
38
            "id",
39
            "slug",
40
            "title",
41
            "start_location__latitude",
42
            "start_location__longitude",
43
        )
44
    )
45

46

47
def list_public_events(query=None, visibility_filter=None, order="start_time"):
1✔
48
    """
49
    List public events with optional filtering and ordering
50

51
    Args:
52
        query: Search term for title, host username, location
53
        visibility_filter: 'open' or 'invite' to filter by visibility
54
        order: 'start_time' or '-start_time' for ascending/descending
55

56
    Returns:
57
        QuerySet of Event objects
58
    """
59
    from .models import Event
1✔
60
    from .enums import EventVisibility
1✔
61

62
    # Base queryset: public events only, not deleted
63
    qs = Event.objects.filter(
1✔
64
        visibility__in=[EventVisibility.PUBLIC_OPEN, EventVisibility.PUBLIC_INVITE],
65
        is_deleted=False,
66
    ).select_related("host", "start_location")
67

68
    # Search filter
69
    if query:
1✔
70
        qs = qs.filter(
1✔
71
            Q(title__icontains=query)
72
            | Q(host__username__icontains=query)
73
            | Q(start_location__title__icontains=query)
74
        )
75

76
    # Visibility filter
77
    if visibility_filter == "open":
1✔
78
        qs = qs.filter(visibility=EventVisibility.PUBLIC_OPEN)
1✔
79
    elif visibility_filter == "invite":
1✔
80
        qs = qs.filter(visibility=EventVisibility.PUBLIC_INVITE)
1✔
81

82
    # Ordering
83
    return qs.order_by(order)
1✔
84

85

86
def user_has_joined(event, user):
1✔
87
    """Check if user has joined event (HOST or ATTENDEE)"""
88
    from .models import EventMembership
1✔
89
    from .enums import MembershipRole
1✔
90

91
    return EventMembership.objects.filter(
1✔
92
        event=event, user=user, role__in=[MembershipRole.HOST, MembershipRole.ATTENDEE]
93
    ).exists()
94

95

96
def list_user_invitations(user):
1✔
97
    """
98
    Get pending invitations for a user
99

100
    Returns:
101
        QuerySet of EventInvite objects with event, host, location prefetched
102
    """
UNCOV
103
    from .models import EventInvite
×
UNCOV
104
    from .enums import InviteStatus
×
105

UNCOV
106
    return (
×
107
        EventInvite.objects.filter(
108
            invitee=user, status=InviteStatus.PENDING, event__is_deleted=False
109
        )
110
        .select_related("event", "event__host", "event__start_location")
111
        .order_by("created_at")
112
    )
113

114

115
# PHASE 3 SELECTORS
116

117

118
def get_event_detail(slug):
1✔
119
    """
120
    Get event with all related data for detail page
121

122
    Returns:
123
        Event object with prefetched relationships
124
    """
125
    from .models import Event
1✔
126

127
    return (
1✔
128
        Event.objects.select_related("host", "start_location")
129
        .prefetch_related("locations__location", "memberships__user")
130
        .get(slug=slug, is_deleted=False)
131
    )
132

133

134
def user_role_in_event(event, user):
1✔
135
    """
136
    Determine user's role in event
137

138
    Returns:
139
        'HOST' | 'ATTENDEE' | 'VISITOR'
140
    """
141
    from .models import EventMembership
1✔
142
    from .enums import MembershipRole
1✔
143

144
    if event.host == user:
1✔
145
        return "HOST"
1✔
146

147
    membership = EventMembership.objects.filter(
1✔
148
        event=event, user=user, role__in=[MembershipRole.ATTENDEE]
149
    ).first()
150

151
    if membership:
1✔
152
        return "ATTENDEE"
1✔
153

154
    return "VISITOR"
1✔
155

156

157
def list_event_attendees(event):
1✔
158
    """
159
    Get all attendees (HOST + ATTENDEE roles)
160

161
    Returns:
162
        QuerySet of EventMembership objects with user info
163
    """
164
    from .models import EventMembership
1✔
165
    from .enums import MembershipRole
1✔
166

167
    return (
1✔
168
        EventMembership.objects.filter(
169
            event=event, role__in=[MembershipRole.HOST, MembershipRole.ATTENDEE]
170
        )
171
        .select_related("user")
172
        .order_by("joined_at")
173
    )
174

175

176
def list_chat_messages(event, limit=20):
1✔
177
    """
178
    Get latest chat messages for event
179

180
    Args:
181
        event: Event object
182
        limit: Max messages to return (default 20)
183

184
    Returns:
185
        List of EventChatMessage ordered oldest first
186
    """
187
    from .models import EventChatMessage
1✔
188

189
    # Get latest N messages in descending order, then reverse to oldest-first
190
    messages = list(
1✔
191
        EventChatMessage.objects.filter(event=event)
192
        .select_related("author")
193
        .order_by("-created_at")[:limit]
194
    )
195
    return messages[::-1]  # Reverse to show oldest first
1✔
196

197

198
def get_join_request(event, user):
1✔
199
    """
200
    Get user's pending join request for event (if exists)
201

202
    Returns:
203
        EventJoinRequest or None
204
    """
205
    from .models import EventJoinRequest
×
206
    from .enums import JoinRequestStatus
×
207

208
    return EventJoinRequest.objects.filter(
×
209
        event=event, requester=user, status=JoinRequestStatus.PENDING
210
    ).first()
211

212

213
def list_pending_join_requests(event):
1✔
214
    """
215
    Get pending join requests for event (host only)
216

217
    Returns:
218
        QuerySet of EventJoinRequest objects
219
    """
220
    from .models import EventJoinRequest
1✔
221
    from .enums import JoinRequestStatus
1✔
222

223
    return (
1✔
224
        EventJoinRequest.objects.filter(event=event, status=JoinRequestStatus.PENDING)
225
        .select_related("requester")
226
        .order_by("created_at")
227
    )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc