Beispiel #1
0
class TestVerification(unittest.TestCase):
  """Verifications Handling Test Cases
  
  PubSubHubbub 0.3 Compliant, async mode only:
  2xx - Verify success, subscription confirmed
  404 - Disagree with the subscription, verify should not be retried
  xxx - Verify temporarily failed, please retry later
  """

  def setUp(self):
    self.application = webapp.WSGIApplication([
      (WORKER['subbub'] + ".*",PushCallback)
      ],debug=True)
    self.channel = Channel(title="Test Channel",
	topic="http://dummychannel.dev/atom",
	status="subscribing") 
    self.channel.put()

  def tearDown(self):
    self.channel.delete()

  def get(self,
          key=None,
	  mode=None,
	  topic=None,
	  challenge=None,
	  token=None):
    """HTTP GET a verify request"""
    url = WORKER['subbub']
    if key: url += key + "?"
    if mode: url += "hub.mode=" + mode
    if topic: url += "&hub.topic=" + topic
    if challenge: url += "&hub.challenge=" + challenge
    if token: url += "&hub.verify_token=" + token
    app = TestApp(self.application)
    return app.get(url, expect_errors=True)

  def verify(self, 
             key=None, 
	     topic=None, 
	     challenge="venus",
             mode="subscribe", 
	     token=HUB["token"]):
    """Simulate a push verify request
    """
    if not key: key = str(self.channel.key())
    if not topic: topic = self.channel.topic
    response = self.get(key=key,
	            mode=mode,
		    topic=topic,
		    challenge=challenge,
		    token=token)
    return response

  def testAllParamsOK(self):
    """Expect 200 OK if all params match.

    Expect hub.challenge.
    """
    challenge = "venus"
    response = self.verify()
    self.assertEqual("200 OK", response.status)
    self.assertEqual(challenge, response.body)
    # Refetch the instance from the datastore, 
    # so its attributes get updated. 
    channel = Channel.get(self.channel.key())
    self.assertEqual(channel.status, "subscribed")

  def testVerifyTokenNotMatch(self):
    """Expect 404 Not Found if the verify token not match.

    The (un)subscribe request must be initiated by someone else, or the
    token is broken. Hub will not retry.
    """
    response = self.verify(token="brokentoken")
    self.assertEqual("404 Not Found", response.status)

  def testCallbackNotMatch(self):
    """Expect 404 Not Found if callback not found.

    The key associated with callback url could not be found in the
    datastore. Hub will not retry.
    """
    response = self.verify(key="randomekeystring")
    self.assertEqual("404 Not Found", response.status)

  def testTopicNotMatch(self):
    """Expect 404 Not Found if topic not match

    The topic does not match with the record in datastore. Hub will
    not retry.
    """
    response = self.verify(topic="http://random.dev/atom")
    self.assertEqual("404 Not Found", response.status)

  def testModeNotMatch(self):
    """Expect 404 Not Found if hub.mode not match
    """
    response = self.verify(mode="unsubscribe")
    self.assertEqual("404 Not Found", response.status)
Beispiel #2
0
class TestNotification(unittest.TestCase):
  """Notification Test Cases

  PubSubHubbub 0.3:
  202 - Notification accepted, added to taskqueue
  204 - Ignored, Payload not valid
  2xx - General notify success
  xxx - Fail, please retry the notification later

  "Subscribers SHOULD respond to notifications as quickly as possible;
  their success response code SHOULD only indicate receipt of the
  message, not acknowledgment that it was successfully processed by the
  subscriber." 
    -- Section 7.3, PubSubHubbub Core 0.3
  """
  def setUp(self):
    self.application = webapp.WSGIApplication([
      (WORKER['subbub'] + ".*",PushCallback)
      ],debug=True)
    self.channel = Channel(title="Test Channel",
	topic="http://dummychannel.dev/atom",
	status="subscribed") 
    self.channel.put()
    self.atom = open("test/atom.xml", "r").read()

  def tearDown(self):
    self.channel.delete()

  def notify(self, key, type, body):
    """HTTP POST notification
    """
    app = TestApp(self.application)
    if type == "rss":
      ct = "application/rss+xml" 
    elif type == "atom":
      ct = "application/atom+xml"
    else:
      ct = type
    response = app.post(WORKER["subbub"] + key,
             params=body,
	     content_type=ct,
	     expect_errors=True)
    return response

  def testNotifyAtomAsAtom(self):
    """Expect 202 Accepted if notify atom as atom
    """
    response = self.notify(str(self.channel.key()), "atom", self.atom)
    self.assertEqual("202 Accepted", response.status)

  def testNotifyAtomAsRss(self):
    """Expect 202 Accepted if notify atom as rss

    Success regardless of content-type not match.
    """
    response = self.notify(str(self.channel.key()), "rss", self.atom)
    self.assertEqual("202 Accepted", response.status)

  def testNotifyKeyBroken(self):
    """Expect 204 No Content if the notify key broken

    We do not support aggregated atom feeds for now.
    """
    response = self.notify("brokenkeystring", "atom", self.atom)
    self.assertEqual("204 No Content", response.status)

  def testNotifyKeyMissing(self):
    """Expect 204 No Content if the notify key missing
    """
    response = self.notify("", "atom", self.atom)
    self.assertEqual("204 No Content", response.status)

  def testNotifyEmptyPayload(self):
    """Expect 204 No Content if the notify payload empty
    """
    response = self.notify(str(self.channel.key()), "atom", "")
    self.assertEqual("204 No Content", response.status)

  def testBadContentType(self):
    """Expect 204 No Content if notify content type not match
    """
    response = self.notify(str(self.channel.key()),
	"application/x-www-form-urlencoded",
	self.atom)
    self.assertEqual("204 No Content", response.status)

  def testMissingContentType(self):
    """Expect 204 No Content if notify content type missing
    """
    response = self.notify(str(self.channel.key()), "", self.atom)
    self.assertEqual("204 No Content", response.status)