class ConferenceTestCase(BaseEndpointAPITestCase):
    """ Endpoint API unit tests. """

    def setUp(self):
        super(ConferenceTestCase, self).setUp()
        self.api = ConferenceApi()

    def tearDown(self):
        super(ConferenceTestCase, self).tearDown()

    def testLogin(self):
        """TEST: User login simulation"""

        assert not users.get_current_user()
        self.login()
        assert users.get_current_user().email() == '*****@*****.**'
        self.login(is_admin=True)
        assert users.is_current_user_admin()
        self.logout()
        assert not users.get_current_user()

    def testGetConferenceSessions(self):
        """ TEST: Return all sessions for a given conference"""
        self.initDatabase()

        conf = Conference.query(Conference.name == 'room #1').fetch(1)[0]
        container = CONF_GET_REQUEST.combined_message_class(websafeConferenceKey=conf.key.urlsafe())
        # manually fetch conference sessions and compare it against response
        sessions = {str(s.key.urlsafe()): s for s in conf.sessions.fetch()}

        r = self.api.getConferenceSessions(container)
        r_sessions = r.items

        assert len(r_sessions) == len(sessions), 'returned an invalid number of sessions'
        for r_session in r_sessions:
            assert sessions[r_session.websafeKey], 'returned an invalid session websafeKey'

    def testQuerySession(self):
        """ TEST: Return sessions for a given query"""
        self.initDatabase()
        form = SessionQueryForms()
        form.filters = [
            SessionQueryForm(field='NAME', operator='EQ', value='Google App Engine')
        ]
        response = self.api.querySessions(form)
        r_sessions = response.items
        assert len(r_sessions) == 1, 'returned an invalid number of sessions'
        assert r_sessions[0].name == 'Google App Engine', 'returned an invalid session'

    def testQueryConferences(self):
        self.initDatabase()
        form = ConferenceQueryForms()
        # verify fixture contains conference
        assert Conference.query(Conference.city == 'London').count() == 1, \
            "This shouldn't fail. Maybe someone messed with database fixture"

        form.filters = [
            ConferenceQueryForm(field='CITY', operator='EQ', value='London')
        ]
        r = self.api.queryConferences(form)
        conferences = r.items
        assert len(conferences) == 1, 'Returned an invalid number of conferences'
        assert conferences[0].city == 'London', 'Returned an invalid conference'

        # check that all conferences are returned when no filter is given
        form.filters = []
        r = self.api.queryConferences(form)
        assert len(r.items) == Conference.query().count(), 'Returned an invalid number of conferences'

    def testGetConferenceSessionsByType(self):
        """ TEST: Return all sessions of a specified type for a given conference"""
        self.initDatabase()

        conf = Conference.query(Conference.name == 'room #4').fetch(1)[0]
        container = SESSION_BY_TYPE_GET_REQUEST.combined_message_class(
            typeOfSession='fun',
            websafeConferenceKey=conf.key.urlsafe()
        )
        r = self.api.getConferenceSessionsByType(container)
        r_sessions = r.items
        assert len(r_sessions) == 1, 'returned an invalid number of sessions'
        assert r_sessions[0].typeOfSession == 'fun', 'returned an invalid session'

    def testGetSessionsBySpeaker(self):
        """ TEST: Return all sessions by a particular speaker"""
        self.initDatabase()

        container = SESSION_BY_SPEAKER_GET_REQUEST.combined_message_class(
            speaker='superman'
        )
        r = self.api.getSessionsBySpeaker(container)
        r_sessions = r.items
        assert len(r_sessions) == 1, 'returned an invalid number of sessions'
        assert r_sessions[0].speaker == 'superman', 'returned an invalid session'

    def testCreateSession(self):
        """ TEST: Create a session open to the organizer of the conference"""
        self.initDatabase()
        conf = Conference.query(Conference.name == 'room #1').fetch(1)[0]

        # fill out session form fields in SESSION_POST_REQUEST
        sessionFields = {
            'name': 'Computer programming',
            'speaker': 'Donald Knuth',
            'typeOfSession': 'educational',
            'date': '2015-08-6',
            'startTime': '11:00',
            'duration': 100
        }

        form = SessionForm(**sessionFields)
        form.check_initialized()
        container = SESSION_POST_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
            **sessionFields
        )

        # get current session count
        initialCount = conf.sessions.count()

        # Attempt to add a session without being logged in
        try:
            r = self.api.createSession(container)
            assert False, 'UnauthorizedException should of been thrown...'
        except UnauthorizedException:
            pass
        # make sure a session wasn't added
        count = conf.sessions.count()
        assert count == initialCount, 'Only the organizer of the conference may create sessions'

        # Attempt to add a session with a logged in but unauthorized user.
        self.login(email='*****@*****.**')
        try:
            r = self.api.createSession(container)
            assert False, 'ForbiddenException should of been thrown...'
        except ForbiddenException:
            pass
        # make sure a session wasn't added
        count = conf.sessions.count()
        assert count == initialCount, 'Only the organizer of the conference may create sessions'

        # Finally, add session using the authorized user
        self.login(email=conf.organizerUserId)
        r = self.api.createSession(container)
        count = conf.sessions.count()
        assert count == initialCount + 1, 'Failed to add session to conference'

    def testAddSessionToWishlist(self):
        """ TEST: Add session to the user's wishlist """
        self.initDatabase()

        session = Session.query(Session.name == 'Intro to Poker').get()
        swsk = session.key.urlsafe()
        container = SESSION_WISHLIST_POST_REQUEST.combined_message_class(
            websafeSessionKey=swsk
        )
        self.login()  # login as default user
        r = self.api.addSessionToWishlist(container)
        profile = ndb.Key(Profile, self.getUserId()).get()
        assert r.data and session.key in profile.wishList, "Failed to add session to user's wish list"

    def testRemoveSessionFromWishlist(self):
        """ TEST: Remove session from user's wishlist """
        self.initDatabase()

        self.login()  # login as default user
        # verify database fixture
        prof = ndb.Key(Profile, self.getUserId()).get()
        session = Session.query(Session.name == 'Intro to Poker').get()
        assert session and len(prof.wishList) == 0, \
            "This shouldn't fail. Maybe someone messed with database fixture"
        # manually add a session to user's wishlist
        prof.wishList.append(session.key)
        prof.put()

        # build request
        container = SESSION_WISHLIST_POST_REQUEST.combined_message_class(
            websafeSessionKey=session.key.urlsafe()
        )
        # remove session from users wishlist
        r = self.api.removeSessionFromWishlist(container)
        # re-fetch profile then verify session was removed
        prof = prof.key.get()
        assert r.data and session.key not in prof.wishList, "Failed to remove session from user's wish list"

    def testGetSessionsInWishlist(self):
        """ TEST: Get sessions in user's wish list """
        self.initDatabase()

        self.login()  # login as default user
        profile = ndb.Key(Profile, self.getUserId()).get()
        pSessionKeys = profile.wishList

        assert len(pSessionKeys) == 0, "This shouldn't fail. Maybe someone messed with database fixture"

        r = self.api.getSessionsInWishlist(message_types.VoidMessage())
        assert len(r.items) == 0, "Returned an invalid number of sessions"

        # add a session to user's wish list
        session = Session.query().get()
        pSessionKeys.append(session.key)
        profile.put()

        # check that user's wishlist was updated
        r = self.api.getSessionsInWishlist(message_types.VoidMessage())
        assert len(r.items) == 1, "Returned an invalid number of sessions"
        assert r.items[0].websafeKey == session.key.urlsafe(), "Returned an invalid session"

    def testGetProfile(self):
        """ TEST: Get user's profile  """
        self.initDatabase()
        try:
            # only logged in users have a profile
            self.api.getProfile(message_types.VoidMessage())
            assert False, 'UnauthorizedException should of been thrown'
        except UnauthorizedException:
            pass

        # login and retrieve the profile
        self.login()
        prof = ndb.Key(Profile, self.getUserId()).get()
        # Add conferences to conferenceKeysToAttend so we can verify the returned keys are web safe
        keys = Conference.query().fetch(keys_only=True)
        prof.conferenceKeysToAttend = keys
        prof.put()

        r = self.api.getProfile(message_types.VoidMessage())
        assert r.mainEmail == '*****@*****.**', 'Returned an invalid user profile'
        assert len(r.conferenceKeysToAttend) > 0, 'Returned an invalid number of conference keys'
        # verify that all keys are urlsafe
        websafeKeys = [key.urlsafe() for key in keys]
        for websafeKey in r.conferenceKeysToAttend:
            assert websafeKey in websafeKeys, 'Returned an invalid key'

    def testCreateConference(self):
        """ TEST: Create new conference."""
        self.initDatabase()
        try:
            # only logged in users may create conferences
            self.api.createConference(ConferenceForm())
            assert False, 'UnauthorizedException should of been thrown'
        except UnauthorizedException:
            pass

        # login and create a conference
        self.login()

        now = datetime.datetime.now()
        # first test using an invalid conference
        conf = {
            'name': 'New Conference',
            'topics': ['misc'],
            'city': 'Baton Rouge',
            'startDate': str(now + datetime.timedelta(days=5)),
            'endDate': str(now),
            'maxAttendees': 100
        }

        # Attempt to add a conference where startDate > endDate. (this should fail)
        try:
            r = self.api.createConference(ConferenceForm(**conf))
            assert False, 'BadRequestException should of been thrown...'
        except BadRequestException:
            pass
        # make sure conference wasn't added
        assert Conference.query(Conference.name == 'New Conference').count() == 0, \
            'A conference with startDate > endDate should not be added to the database'

        # add a conference using valid startDate and endDate
        conf['startDate'] = str(now)
        conf['endDate'] = str(now + datetime.timedelta(days=5))
        r = self.api.createConference(ConferenceForm(**conf))
        assert Conference.query(Conference.name == 'New Conference').count() == 1, \
            'Failed to add conference to datastore'
        assert r.name == 'New Conference', 'Returned an invalid conference'

    def testUpdateConference(self):
        """ TEST: Update conference w/provided fields & return w/updated info """
        self.initDatabase()

        self.login()
        conf = Conference.query(ancestor=ndb.Key(Profile, self.getUserId())).get()
        key = conf.key
        assert conf.name != 'testUpdateConference', "This shouldn't fail. Maybe someone messed with database fixture"

        # converting `conf` to a dictionary doesn't format the values properly to send request.
        # so first convert it to a form, then to a dictionary
        data = formToDict(conf.toForm())
        data['name'] = 'testUpdateConference'
        container = CONF_POST_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
            **data
        )

        r = self.api.updateConference(container)
        assert r.name == 'testUpdateConference', 'Returned an invalid conference'
        assert r.name == key.get().name, 'Failed to update datastore'

    def testGetConference(self):
        """ TEST: Return requested conference (by websafeConferenceKey) """
        self.initDatabase()

        self.login()
        conf = Conference.query(ancestor=ndb.Key(Profile, self.getUserId())).get()

        container = CONF_GET_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
        )

        r = self.api.getConference(container)
        assert r.websafeKey == conf.key.urlsafe(), 'Returned an invalid conference'

    def testGetConferencesCreated(self):
        """ TEST: Return conferences created by user """
        self.initDatabase()

        self.login()
        conferences = Conference.query(ancestor=ndb.Key(Profile, self.getUserId())).fetch()
        assert len(conferences) == 3, "This shouldn't fail. Maybe someone messed with database fixture"

        r = self.api.getConferencesCreated(message_types.VoidMessage())

        assert len(r.items) == len(conferences), 'Returned an invalid number of conferences'
        # verify that every key matches the returned set
        keys = [c.key.urlsafe() for c in conferences]
        for conf in r.items:
            assert conf.websafeKey in keys, 'Returned an invalid conference key (websafe)'

    def testGetConferencesToAttend(self):
        """ TEST: Get list of conferences that user has registered for """
        self.initDatabase()

        self.login()
        prof = ndb.Key(Profile, self.getUserId()).get()
        count = len(prof.conferenceKeysToAttend)
        assert count == 0, "This shouldn't fail. Maybe someone messed with database fixture"

        r = self.api.getConferencesToAttend(message_types.VoidMessage())
        assert len(r.items) == count, 'Returned an invalid number of conferences'

        # register to a conference and test again
        key = Conference.query().get().key
        prof.conferenceKeysToAttend.append(key)
        prof.put()

        r = self.api.getConferencesToAttend(message_types.VoidMessage())
        assert len(r.items) == count + 1, 'Returned an invalid number of conferences'
        assert r.items[0].websafeKey == key.urlsafe(), 'Returned an invalid websafeKey'

    def testRegisterForConference(self):
        """ TEST: Register user for selected conference."""
        self.initDatabase()

        # verify database fixture
        self.login()
        prof = ndb.Key(Profile, self.getUserId()).get()
        conf = Conference.query(Conference.name == 'room #2').get()
        assert conf and conf.seatsAvailable == 1 and len(prof.conferenceKeysToAttend) == 0, \
            "This shouldn't fail. Maybe someone messed with database fixture"

        container = CONF_GET_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
        )

        # register to conference
        r = self.api.registerForConference(container)

        # re-fetch profile and conference, then check if user was properly registered
        prof = prof.key.get()
        conf = conf.key.get()
        assert r.data, 'Returned an invalid response'
        assert len(prof.conferenceKeysToAttend) == 1, "Failed to add conference to user's conferenceKeysToAttend"
        assert conf.seatsAvailable == 0, 'Failed to decrement available seats'

        # Verify users cant re-register to conferences that are already in user's conferenceKeysToAttend.
        container = CONF_GET_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
        )
        try:
            r = self.api.registerForConference(container)
            assert False, 'ConflictException should of been thrown...'
        except ConflictException:
            pass
        # re-fetch profile and check that the user wasn't re-registered
        prof = prof.key.get()
        assert len(prof.conferenceKeysToAttend) == 1, "User's can't registered to the same conference"

        # Login as a different user and attempt to register a conference with zero seats available
        self.login(email='*****@*****.**')
        prof = ndb.Key(Profile, self.getUserId()).get()
        assert len(prof.conferenceKeysToAttend) == 0, "This shouldn't fail. Maybe someone messed with database fixture"
        try:
            r = self.api.registerForConference(container)
            assert False, 'ConflictException should of been thrown...'
        except ConflictException:
            pass
        # re-fetch profile and conference
        prof = prof.key.get()
        conf = conf.key.get()
        assert len(prof.conferenceKeysToAttend) == 0, "User's can't register to a conference with zero seats available."
        assert conf.seatsAvailable == 0, "seatsAvailable shouldn't have changed since user never registered..."

    def testUnregisterFromConference(self):
        """ TEST: Unregister user for selected conference."""
        self.initDatabase()

        # verify database fixture
        self.login()
        prof = ndb.Key(Profile, self.getUserId()).get()
        conf = Conference.query(Conference.name == 'room #2').get()
        assert conf and conf.seatsAvailable == 1 and len(prof.conferenceKeysToAttend) == 0, \
            "This shouldn't fail. Maybe someone messed with database fixture"

        prof.conferenceKeysToAttend.append(conf.key)
        prof.put()

        container = CONF_GET_REQUEST.combined_message_class(
            websafeConferenceKey=conf.key.urlsafe(),
        )

        # unregister conference
        r = self.api.unregisterFromConference(container)

        # re-fetch profile and conference, then check if user was properly unregistered
        prof = prof.key.get()
        conf = conf.key.get()
        assert r.data, 'Returned an invalid response'
        assert len(prof.conferenceKeysToAttend) == 0, "Failed to remove conference from user's conferenceKeysToAttend"
        assert conf.seatsAvailable == 2, 'Failed to increment available seats'

    def testSaveProfile(self):
        self.initDatabase()
        self.login()

        prof = ndb.Key(Profile, self.getUserId()).get()
        assert TeeShirtSize(prof.teeShirtSize) == TeeShirtSize.NOT_SPECIFIED, \
            "This shouldn't fail. Maybe someone messed with database fixture"

        form = ProfileMiniForm(
            displayName='testSaveProfile',
            teeShirtSize=TeeShirtSize.XL_M
        )
        r = self.api.saveProfile(form)

        # validate response
        assert r.displayName == 'testSaveProfile' and \
               TeeShirtSize(r.teeShirtSize) == TeeShirtSize.XL_M, 'Returned invalid response'

        # re-fetch profile and validate values in datastore
        prof = prof.key.get()
        assert prof.displayName == 'testSaveProfile' and \
               TeeShirtSize(prof.teeShirtSize) == TeeShirtSize.XL_M, 'Failed to save profile in datastore'

    def testGetAnnouncement(self):
        """ TEST: Return Announcement from memcache."""
        self.initDatabase()

        # Verify database fixture
        confs = Conference.query(ndb.AND(
            Conference.seatsAvailable <= 5,
            Conference.seatsAvailable > 0)
        ).fetch()
        assert len(confs) == 1 and confs[0].name == 'room #2' and None == memcache.get(MEMCACHE_ANNOUNCEMENTS_KEY), \
            "This shouldn't fail. Maybe someone messed with database fixture"

        # Since an announcement was never set `getAnnouncement()` should return an empty StringMessage
        response = self.api.getAnnouncement(message_types.VoidMessage())
        assert response.data == '', 'Expected an empty string since no announcement was set'

        # set announcement
        request = webapp2.Request.blank('/crons/set_announcement')
        response = request.get_response(main.app)
        # validate http status
        assert response.status_int == 204, 'Invalid response expected 204 but got %d' % response.status_int

        # Verify room #2 is listed in the announcement
        response = self.api.getAnnouncement(message_types.VoidMessage())
        assert 'room #2' in response.data, 'Announcement is missing a conference'

    def testConferenceEmailConfirmation(self):
        """ TEST: Send email to organizer confirming creation of Conference """
        self.mail_stub = self.testbed.get_stub(testbed.MAIL_SERVICE_NAME)
        self.initDatabase()
        self.login()

        now = datetime.datetime.now()
        r = self.api.createConference(ConferenceForm(
            name='New Conference',
            organizerUserId=self.getUserId(),
            topics=['misc'],
            city='Baton Rouge',
            startDate=str(now),
            endDate=str(now + datetime.timedelta(days=5)),
            maxAttendees=100
        ))
        tasks = self.taskqueue_stub.get_filtered_tasks()
        assert len(tasks) != 0, 'No tasks were added to queue'

        # Run the task
        request = webapp2.Request.blank(tasks[0].url + '?' + tasks[0].payload)
        request.method = tasks[0].method
        response = request.get_response(main.app)
        assert response.status_int == 200, 'Invalid response expected 200 but got %d' % response.status_int
        # verify email was sent
        prof = ndb.Key(Profile, self.getUserId()).get()
        messages = self.mail_stub.get_sent_messages(to=prof.mainEmail)
        assert len(messages) == 1, 'Failed to send confirmation email'

    def testGetFeaturedSpeaker(self):
        """ TEST: Returns the featured speakers and their registered sessions from memcache. """
        self.initDatabase()
        # Verify database fixture
        speakers = {}
        for session in Session.query():
            assert speakers.get(session.speaker.name, None) is None, \
                "This shouldn't fail. Maybe someone messed with database fixture"
            speakers[session.name] = session.key
        assert None == memcache.get(MEMCACHE_FEATURED_SPEAKER_KEY), \
            "This shouldn't fail. Maybe someone messed with database fixture"

        # Since a featured speaker was never set `getFeaturedSpeaker()` should return an empty StringMessage
        response = self.api.getFeaturedSpeaker(message_types.VoidMessage())
        assert response.data == '', 'Expected an empty string since no announcement was set'

        # Login and grab a conference owned by the current user
        self.login()
        conf = Conference.query(ancestor=ndb.Key(Profile, self.getUserId())).get()

        # Add 2 sessions with the same speaker using `createSession` endpoint
        sessions = [
            {'name': 'PHP', 'speaker': 'hitler', 'typeOfSession': 'educational',
             'date': str(conf.startDate), 'startTime': '08:00', 'duration': 60},
            {'name': 'Python', 'speaker': 'hitler', 'typeOfSession': 'educational',
             'date': str(conf.startDate), 'startTime': '12:30', 'duration': 60},
        ]
        initial_count = Session.query().count()
        for session in sessions:
            form = SessionForm(**session)
            form.is_initialized()
            container = SESSION_POST_REQUEST.combined_message_class(
                websafeConferenceKey=conf.key.urlsafe(),
                **session
            )
            self.api.createSession(container)
        count = Session.query().count()
        assert count == initial_count + 2, 'Failed to add sessions to conference...'

        tasks = self.taskqueue_stub.get_filtered_tasks()
        assert len(tasks) == 2, 'No tasks were added to queue'
        for task in tasks:
            request = webapp2.Request.blank(task.url + '?' + task.payload)
            request.method = task.method
            response = request.get_response(main.app)
            # validate http status
            assert response.status_int == 204, 'Invalid response expected 204 but got %d' % response.status_int

        # Verify featured speaker has been updated
        response = self.api.getFeaturedSpeaker(message_types.VoidMessage())
        data = response.data
        memData = memcache.get(MEMCACHE_FEATURED_SPEAKER_KEY)
        assert 'hitler' in memData and \
               'PHP' in memData and \
               'Python' in memData, 'Failed to add featured speaker to memcache'
        assert 'hitler' in data and \
               'PHP' in data and \
               'Python' in data, 'Returned an invalid featured speaker'

    def testTask3QueryProblem(self):
        """ TEST: Solve task 3 "the query related problem"  """
        # init and verify database fixture
        self.initDatabase()
        workshopSessions = Session.query(Session.typeOfSession == 'workshop').fetch()
        assert len(workshopSessions) == 2, "This shouldn't fail. Maybe someone messed with database fixture"
        # manually get the solution so we can compare it against the response
        validSessions = []
        for session in Session.query(Session.startTime < datetime.datetime.strptime('19:00', '%H:%M').time()):
            if session not in workshopSessions:
                validSessions.append(session)
        assert len(validSessions) > 0, "This shouldn't fail. Maybe someone messed with database fixture"

        # create a query using `sessionQueryForms()` and add 2 inequalities
        form = SessionQueryForms()
        form.filters = [
            SessionQueryForm(field='TYPE_OF_SESSION', operator='NE', value='workshop'),
            SessionQueryForm(field='START_TIME', operator='LT', value='19:00')
        ]
        response = self.api.querySessions(form)
        # evaluate the response
        sessions = response.items
        assert len(sessions) == len(validSessions), 'Returned an invalid number of sessions'
        validKeys = [v.key.urlsafe() for v in validSessions]
        for s in sessions:
            assert s.websafeKey in validKeys, 'Returned an invalid session'

        # ----- Attempt a 9 inequality query -----------
        # Create a unique session
        uniqueSession = {'name': 'BONUS ROUND', 'speaker': Speaker(name='BONUS ROUND'), 'typeOfSession': 'BONUS ROUND',
                         'date': datetime.datetime.strptime('2015-12-12', '%Y-%m-%d'),
                         'startTime': datetime.time(hour=3), 'duration': 200}
        # verify this session is unique
        for key, value in uniqueSession.iteritems():
            count = Session.query(Session._properties[key] == value).count()
            assert count == 0, 'Ahhh failed to setup bonus round, maybe someone messed with the database fixture'

        # add unique session to database
        conf = Conference.query().get()
        c_id = Session.allocate_ids(size=1, parent=conf.key)[0]
        uniqueSession['key'] = ndb.Key(Session, c_id, parent=conf.key)
        Session(**uniqueSession).put()

        # create a form with multiple inequalities
        inequalities = [
            {'field': 'START_TIME', 'operator': 'GTEQ', 'value': '02:30'},
            {'field': 'DATE', 'operator': 'LTEQ', 'value': '2015-12-12'},
            {'field': 'DURATION', 'operator': 'GT', 'value': '30'}
        ]
        form = SessionQueryForms()
        for inequality in inequalities:
            form.filters.append(SessionQueryForm(**inequality))

        # grab all sessions (EXCLUDING unique session)
        sessions = Session.query(Session.key != uniqueSession['key']).fetch()
        assert len(sessions) == 6
        # add additional inequalities using the session names
        for session in sessions:
            form.filters.append(SessionQueryForm(
                field='NAME',
                operator='NE',
                value=session.name
            ))
        # 9 inequality filters
        assert len(form.filters) == 9, 'Ahhh failed to setup bonus round, expected 9 inequality filters'
        # From the way the test was setup, `START_TIME` will be the only
        # property filtered by datastore. Everything else will be filtered using python.

        # make the query using the 9 inequality filters to retrieve the `uniqueSession`
        response = self.api.querySessions(form)
        assert len(response.items) == 1
        assert response.items[0].name == 'BONUS ROUND'
示例#2
0
 def get(self):
     """Set Announcement in Memcache."""
     # TODO 1
     self.response.out.write(ConferenceApi.getAnnouncement())