=========================
Use cases for aws.authrss
=========================

``aws.authrss`` is a simple component that enables authenticated users of a
Plone site to subscribe to RSS feeds that show all contents the same logged in
user may view in the Plone site.

Some initializations and preliminary checkins
=============================================

Our work environment::

  >>> from lxml import etree
  >>> import transaction
  >>> portal = layer['portal']
  >>> portal_url = portal.absolute_url()
  >>> workflow_tool = portal.portal_workflow

Checking global syndication settings

  >>> portal.portal_syndication.isSiteSyndicationAllowed()
  True

Checking our component is instaled::

  >>> qi_tool = portal['portal_quickinstaller']
  >>> qi_tool.isProductInstalled('aws.authrss')
  True

Checking the required actions are available::

  >>> actions_tool = portal['portal_actions']
  >>> 'rss_token' in actions_tool['user'].keys()
  True
  >>> 'private_rss' in actions_tool['document_actions'].keys()
  True

We grant reviewer role to the member such he will see pending content::

  >>> from plone.app.testing import setRoles, TEST_USER_ID
  >>> setRoles(portal, TEST_USER_ID, ['Member', 'Reviewer'])
  >>> transaction.commit()

We need an anonymous user, a reviewer and a manager::

  >>> anon_browser = layer.anonymous_browser()
  >>> member_browser = layer.member_browser()
  >>> mgr_browser = layer.manager_browser()

The manager builds the 'foo' folder ::

  >>> mgr_browser.open(portal_url + '/createObject?type_name=Folder')
  >>> mgr_browser.getControl(name='title').value = 'Foo'
  >>> mgr_browser.getControl(name='form.button.save').click()
  >>> foo_folder_url = mgr_browser.url
  >>> mgr_browser.open(foo_folder_url +
  ...                  '/content_status_modify?workflow_action=publish')
  >>> foo_folder_url
  'http://nohost/plone/foo/'

And enables syndication on that folder::

  >>> mgr_browser.open(foo_folder_url + 'synPropertiesForm')
  >>> submit = mgr_browser.getControl(name='form.button.enableSyndication')
  >>> submit.click()
  >>> foo_folder = portal['foo']
  >>> layer.enable_syndication(foo_folder)
  >>> portal.portal_syndication.isSyndicationAllowed(foo_folder)
  True
  >>> transaction.commit()

The anonymous can see this content::

  >>> anon_browser.open(foo_folder_url)
  >>> anon_browser.title.startswith('Foo')
  True

How is the link to the RSS feed?
================================

For the anonymous user
----------------------

The anonymous should have the usual legacy RSS URL::

  >>> anon_browser.open(foo_folder_url)
  >>> tree = etree.HTML(anon_browser.contents)
  >>> links = tree.xpath("//li[@id='document-action-private_rss']/a")
  >>> len(links)
  1
  >>> anon_rss_url = links[0].attrib['href']
  >>> anon_rss_url
  'http://nohost/plone/foo/RSS'

For the authenticated user
--------------------------

An authenticated user could see the RSS link with his own private token::

  >>> member_browser.open(foo_folder_url)
  >>> tree = etree.HTML(member_browser.contents)
  >>> links = tree.xpath("//li[@id='document-action-private_rss']/a")
  >>> len(links)
  1
  >>> member_rss_url = links[0].attrib['href']
  >>> member_rss_url.startswith('http://nohost/plone/foo/AUTH-RSS?token=')
  True

Let's add some content
======================

As the foo folder has no content, there's nothing to view in the RSS feeds,
either the anonymous one or the private RSS feed for the member.

Adding a public 'Title 1' document
----------------------------------

  >>> mgr_browser.open(foo_folder_url + '/createObject?type_name=Document')
  >>> mgr_browser.getControl(name='title').value = 'Title 1'
  >>> mgr_browser.getControl(name='description').value = 'Description 1'
  >>> mgr_browser.getControl(name='form.button.save').click()
  >>> _ = mgr_browser.url
  >>> mgr_browser.open(_ + '/content_status_modify?workflow_action=publish')
  >>> transaction.commit()
  >>> title1_doc_url = _
  >>> 'title-1' in portal['foo'].objectIds()
  True
  >>> title1_doc = portal['foo']['title-1']
  >>> workflow_tool.getInfoFor(title1_doc, 'review_state')
  'published'

Adding a restricted 'Title 2' document
--------------------------------------

Same as above but users must be reviewers to see this one::

  >>> mgr_browser.open(foo_folder_url + '/createObject?type_name=Document')
  >>> mgr_browser.getControl(name='title').value = 'Title 2'
  >>> mgr_browser.getControl(name='description').value = 'Description 2'
  >>> mgr_browser.getControl(name='form.button.save').click()
  >>> _ = mgr_browser.url
  >>> mgr_browser.open(_ + '/content_status_modify?workflow_action=submit')
  >>> transaction.commit()
  >>> title2_doc_url = _
  >>> 'title-2' in portal['foo'].objectIds()
  True
  >>> title2_doc = portal['foo']['title-2']
  >>> workflow_tool.getInfoFor(title2_doc, 'review_state')
  'pending'

Checking the availability of various contents
---------------------------------------------

The anonymous may see the 'Title 1' document::

  >>> anon_browser.open(title1_doc_url)
  >>> anon_browser.url == title1_doc_url
  True

But not the 'Title 2' document::

  >>> anon_browser.open(title2_doc_url)
  Traceback (most recent call last):
  ...
  Unauthorized: ...

The member may see both documents::

  >>> member_browser.open(title1_doc_url)
  >>> member_browser.url == title1_doc_url
  True
  >>> member_browser.open(title2_doc_url)
  >>> member_browser.url == title2_doc_url
  True

Viewing the RSS feed of the Foo folder
======================================

Okay, we are now testing the main feature of this component and show that when
viewing a private feed as anonymous, this feed shows also the elements the
authenticated member is allowed to view::

  >>> anon_browser.open(member_rss_url)
  >>> feed = anon_browser.contents
  >>> feed_urls = layer.rss_feed_urls(feed)
  >>> feed_urls
  ['http://nohost/plone/foo/title-1', 'http://nohost/plone/foo/title-2']

But he cannot view the last URL of the feed::

  >>> anon_browser.open(feed_urls[-1])
  Traceback (most recent call last):
  ...
  Unauthorized: ...

Resetting the personal token
============================



Checking the action link to the personal token
----------------------------------------------

The anonymous cannot reset his token::

  >>> anon_browser.open(portal_url)
  >>> anon_browser.getLink('RSS Token')
  Traceback (most recent call last):
  ...
  LinkNotFoundError

When the member has this link in his personal actions::

  >>> member_browser.open(portal_url)
  >>> link = member_browser.getLink('RSS Token')
  >>> link.url
  'http://nohost/plone/@@personal-rss-token'

Anyway, even if the anonymous knows the URL, he cannot go there::
