653 lines
24 KiB
Perl
653 lines
24 KiB
Perl
# t/atom-post.t
|
|
#
|
|
# Test post via ATOM protocol.
|
|
#
|
|
# This code was forked from the LiveJournal project owned and operated
|
|
# by Live Journal, Inc. The code has been modified and expanded by
|
|
# Dreamwidth Studios, LLC. These files were originally licensed under
|
|
# the terms of the license supplied by Live Journal, Inc, which can
|
|
# currently be found at:
|
|
#
|
|
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
|
#
|
|
# In accordance with the original license, this code and all its
|
|
# modifications are provided under the GNU General Public License.
|
|
# A copy of that license can be found in the LICENSE file included as
|
|
# part of this distribution.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Test::More;
|
|
|
|
BEGIN { $LJ::_T_CONFIG = 1; require "$ENV{LJHOME}/cgi-bin/ljlib.pl"; }
|
|
use LJ::Test;
|
|
|
|
plan skip_all => "AtomAPI authentication is currently broken -- remove?";
|
|
|
|
if (LJ::Test::check_memcache) {
|
|
plan tests => 103;
|
|
}
|
|
else {
|
|
plan skip_all => "Memcache configured but not active.";
|
|
}
|
|
|
|
use XML::Atom::Client;
|
|
use XML::Atom::Entry;
|
|
use XML::Atom::Category;
|
|
use XML::Atom::Feed;
|
|
use DW::Routing;
|
|
|
|
my $u = temp_user();
|
|
my $pass = "foopass";
|
|
$u->set_password($pass);
|
|
$u->update_self( { status => 'A' } );
|
|
|
|
my $api = XML::Atom::Client->new( Version => 1 );
|
|
|
|
my $r;
|
|
|
|
sub do_request {
|
|
my ( $method, $uri, %opts ) = @_;
|
|
|
|
my $authenticate = delete $opts{authenticate};
|
|
my $data = delete $opts{data} || {};
|
|
my $remote = delete $opts{remote} || $u;
|
|
my $password = delete $opts{password} || $remote->password;
|
|
|
|
$uri =~ m!https?://([^.]+)!;
|
|
my $user_subdomain = $1 eq "www" ? "" : $1;
|
|
|
|
my %routing_data = ();
|
|
$routing_data{username} = $user_subdomain if $user_subdomain;
|
|
|
|
my $input = delete $data->{input};
|
|
|
|
$r = routing_request(
|
|
$uri,
|
|
method => $method,
|
|
content => $input,
|
|
setup_http_request => sub {
|
|
if ($authenticate) {
|
|
$api->username( $remote->username );
|
|
$api->password($password);
|
|
$api->munge_request( $_[0] );
|
|
}
|
|
},
|
|
setup_dw_request => sub {
|
|
$_[0]->pnote( $_ => $data->{$_} ) foreach %$data;
|
|
},
|
|
routing_data => \%routing_data,
|
|
);
|
|
}
|
|
|
|
# check subject, etc
|
|
# items that are not defined in the hash to be checked against are ignored
|
|
sub check_entry {
|
|
my ( $atom_entry, $entry_info, $journal ) = @_;
|
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
subtest "check_entry $entry_info->{id} - $entry_info->{title}" => sub {
|
|
ok( $atom_entry, "Got an atom entry back from the server" );
|
|
is( $atom_entry->title, $entry_info->{title}, "atom entry has right title" )
|
|
if defined $entry_info->{title};
|
|
|
|
# having the content body be of type HTML
|
|
# causes newlines to appear for some reason when we try to extract the content as a string
|
|
# so let's just work around it; it should be harmless (as_xml doesn't contain the extra newlines)
|
|
my $event_raw = $entry_info->{content};
|
|
like( $atom_entry->content->body, qr/\s*$event_raw\s*/, "atom entry has right content" )
|
|
if defined $entry_info->{content};
|
|
|
|
is( $atom_entry->id, $entry_info->{atom_id}, "atom id" )
|
|
if defined $entry_info->{atom_id};
|
|
|
|
is( $atom_entry->author->name, $entry_info->{author}, "atom entry author" )
|
|
if defined $entry_info->{author};
|
|
|
|
if ( defined $entry_info->{url} ) {
|
|
my @links = $atom_entry->link;
|
|
is( scalar @links, 2, "got back two links" );
|
|
foreach my $link (@links) {
|
|
if ( $link->rel eq "edit" ) {
|
|
is( $link->href, $journal->atom_base . "/entries/$entry_info->{id}",
|
|
"edit link" );
|
|
}
|
|
else { # alternate
|
|
is( $link->href, $entry_info->{url}, "entry link" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( defined $entry_info->{categories} ) {
|
|
my %tags = map { $_ => 1 } @{ $entry_info->{categories} || [] };
|
|
my %categories = map { $_->term => 1 } $atom_entry->category;
|
|
is( scalar keys %categories, 2, "got back multiple categories" );
|
|
is_deeply( {%categories}, {%tags}, "got back the categories we sent in" );
|
|
}
|
|
};
|
|
}
|
|
|
|
note("Authentication");
|
|
do_request( GET => $u->atom_service_document );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Did not pass any authorization information." );
|
|
is( $r->content_type, "text/plain", "Error content type" );
|
|
|
|
# intentionally break authorization
|
|
do_request( GET => $u->atom_service_document, authenticate => 1, password => $u->password x 3 );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Passed wrong authorization information." );
|
|
|
|
do_request( GET => $u->atom_service_document, authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Successful authentication." );
|
|
|
|
note("Service document introspection.");
|
|
do_request( POST => $u->atom_service_document );
|
|
is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Service document needs GET (even unauthorized)" );
|
|
|
|
do_request( POST => $u->atom_service_document, authenticate => 1 );
|
|
is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Service document needs GET." );
|
|
|
|
do_request( GET => $u->atom_service_document, authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Got service document." );
|
|
like( $r->content_type, qr#^\Qapplication/atomsvc+xml\E#, "Service content type" );
|
|
my $service_document_xml = $r->response_content;
|
|
|
|
note("Categories document.");
|
|
|
|
# populate journal with some tags
|
|
my @journal_tags = qw( a b c );
|
|
LJ::Tags::create_usertag( $u, join( ", ", @journal_tags ), { display => 1 } );
|
|
|
|
do_request( GET => $u->atom_base . "/entries/tags" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Categories document protected by authorization." );
|
|
|
|
do_request( POST => $u->atom_base . "/entries/tags", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, "Categories document needs GET." );
|
|
|
|
do_request( GET => $u->atom_base . "/entries/tags", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Got categories document." );
|
|
like( $r->content_type, qr#^\Qapplication/atomcat+xml\E#, "Categories document type" );
|
|
my $categories_document_xml = $r->response_content;
|
|
|
|
SKIP: {
|
|
skip "No XML::Atom::Service/XML::Atom::Categories module installed.", 10
|
|
unless eval "use XML::Atom::Service; use XML::Atom::Categories; 1;";
|
|
|
|
my $service = XML::Atom::Service->new( \$service_document_xml );
|
|
ok( $service, "Got service document." );
|
|
|
|
my @workspaces = $service->workspace;
|
|
is( scalar @workspaces, 1, "One workspace" );
|
|
is( $workspaces[0]->title, $u->user, "Workspace title" );
|
|
|
|
my @collections = $workspaces[0]->collections;
|
|
is( scalar @collections, 1, "One collection" );
|
|
is( $collections[0]->title, "Entries", "Entries collection title" );
|
|
is( $collections[0]->href, $u->atom_base . "/entries", "Entries collection uri" );
|
|
|
|
my @categories = $collections[0]->categories;
|
|
is( scalar @categories, 1, "One categories link" );
|
|
is( $categories[0]->href, $u->atom_base . "/entries/tags", "Categories collection uri" );
|
|
|
|
my $categories = XML::Atom::Categories->new( \$categories_document_xml );
|
|
@categories = $categories->category;
|
|
is( scalar @categories, 3, "three existing categories" );
|
|
is_deeply(
|
|
{ map { $_->term => 1 } @categories },
|
|
{ map { $_ => 1 } @journal_tags },
|
|
"Journal tags match fetched categories"
|
|
);
|
|
}
|
|
|
|
my $atom_entry; # an XML::Atom::Entry object
|
|
my $entry_obj; # an LJ::Entry object
|
|
my $atom_entry_server; # an XML::Atom::Entry object retrieved from the server
|
|
|
|
$atom_entry = XML::Atom::Entry->new( Version => 1 );
|
|
my $title = "New Post";
|
|
my $content = "Content of my post at " . rand();
|
|
my @tags = qw( foo bar );
|
|
$atom_entry->title($title);
|
|
$atom_entry->content($content);
|
|
foreach my $tag (@tags) {
|
|
my $category = XML::Atom::Category->new( Version => 1 );
|
|
$category->term($tag);
|
|
$atom_entry->add_category($category);
|
|
}
|
|
|
|
note("Create an entry.");
|
|
do_request( POST => $u->atom_base . "/entries", data => { input => $atom_entry->as_xml } );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Entry creation protected by authorization." );
|
|
|
|
do_request(
|
|
POST => $u->atom_base . "/entries",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_CREATED, "POSTed new entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
note("Double-check posted entry.");
|
|
$entry_obj = LJ::Entry->new( $u, jitemid => 1 );
|
|
ok( $entry_obj, "got entry" );
|
|
ok( $entry_obj->valid, "entry is valid" );
|
|
is( $entry_obj->subject_raw, $title, "item has right title" );
|
|
is( $entry_obj->event_raw, $content, "item has right content" );
|
|
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $atom_entry_server->title,
|
|
content => $atom_entry_server->content->body,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig,
|
|
categories => \@tags,
|
|
},
|
|
$u
|
|
);
|
|
|
|
ok( $atom_entry_server->published eq $atom_entry_server->updated, "same publish and edit date" );
|
|
ok( !$atom_entry_server->summary, "no summary; we have the content." );
|
|
|
|
note("List entries");
|
|
do_request( GET => $u->atom_base . "/entries" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Entries feed needs authorization." );
|
|
|
|
do_request( GET => $u->atom_base . "/entries", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Retrieved entry list" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
my $feed = XML::Atom::Feed->new( \$r->response_content );
|
|
my @entries = $feed->entries;
|
|
is( scalar @entries, 1, "Got entry from feed." );
|
|
|
|
note("Retrieve entry");
|
|
do_request( GET => $u->atom_base . "/entries/1" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Retrieving entry needs authorization." );
|
|
|
|
do_request( GET => $u->atom_base . "/entries/12345", authenticate => 1 );
|
|
is( $r->status, $r->NOT_FOUND, "No such entry" );
|
|
is( $r->content_type, "text/plain", "AtomAPI entry content type" );
|
|
|
|
do_request( POST => $u->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_METHOD_NOT_ALLOWED, $u->atom_base . "/entries/1 does not support POST." );
|
|
|
|
do_request( GET => $u->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Retrieved entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $entry_obj->subject_raw,
|
|
content => $entry_obj->event_raw,
|
|
atom_id => $entry_obj->atom_id,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig,
|
|
categories => \@tags
|
|
},
|
|
$u
|
|
);
|
|
ok( $atom_entry_server->published eq $atom_entry_server->updated, "same publish and edit date" );
|
|
ok( !$atom_entry_server->summary, "no summary; we have the content." );
|
|
|
|
note("Edit entry");
|
|
do_request( PUT => $u->atom_base . "/entries/1" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Retrieving entry needs authorization." );
|
|
|
|
do_request( PUT => $u->atom_base . "/entries/12345", authenticate => 1 );
|
|
is( $r->status, $r->NOT_FOUND, "No such entry" );
|
|
is( $r->content_type, "text/plain", "AtomAPI entry content type" );
|
|
|
|
$atom_entry = XML::Atom::Entry->new( Version => 1 );
|
|
$title = "Edited Post";
|
|
$content = "Content of my post at " . rand();
|
|
@tags = qw( foo2 bar2 );
|
|
$atom_entry->id( $atom_entry_server->id );
|
|
$atom_entry->title($title);
|
|
$atom_entry->content($content);
|
|
foreach my $tag (@tags) {
|
|
my $category = XML::Atom::Category->new( Version => 1 );
|
|
$category->term($tag);
|
|
$atom_entry->add_category($category);
|
|
}
|
|
|
|
# put a little bit of time between publish and update
|
|
sleep(1);
|
|
do_request(
|
|
PUT => $u->atom_base . "/entries/1",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_OK, "Edited entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
do_request( GET => $u->atom_base . "/entries/1", authenticate => 1 );
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $title,
|
|
content => $content,
|
|
atom_id => $entry_obj->atom_id,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig,
|
|
categories => \@tags
|
|
},
|
|
$u
|
|
);
|
|
ok( $atom_entry_server->published ne $atom_entry_server->updated,
|
|
"different publish and edit date" );
|
|
|
|
$atom_entry_server->id("123");
|
|
do_request(
|
|
PUT => $u->atom_base . "/entries/1",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry_server->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_BAD_REQUEST, "Mismatched ids" );
|
|
|
|
do_request( DELETE => $u->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Deleted entry" );
|
|
$entry_obj = LJ::Entry->new( $u, jitemid => 1 );
|
|
isnt( $entry_obj->valid, "Entry confirmed deleted" );
|
|
|
|
do_request( PUT => $u->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->NOT_FOUND, "Trying to edit deleted entry" );
|
|
|
|
note("Checking community functionality.");
|
|
{
|
|
my $memberof_cu = temp_comm();
|
|
my $nonmemberof_cu = temp_comm();
|
|
$u->join_community( $memberof_cu, 1, 1 );
|
|
|
|
my $another_u = temp_user(); # another member of the community
|
|
$another_u->set_password($pass);
|
|
$another_u->join_community( $memberof_cu, 1, 1 );
|
|
|
|
my $admin_u = temp_user(); # an administrator of the community
|
|
$admin_u->set_password($pass);
|
|
$admin_u->join_community( $memberof_cu, 1, 1 );
|
|
LJ::set_rel( $memberof_cu->userid, $admin_u->userid, "A" );
|
|
|
|
note("Service document introspection (community).");
|
|
|
|
# unauthenticated to community
|
|
do_request( GET => $memberof_cu->atom_service_document );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Service document protected by authorization." );
|
|
|
|
# community you aren't a member of
|
|
do_request( GET => $nonmemberof_cu->atom_service_document, authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK,
|
|
"Not a member of the community, but we still get the service document for the user (which doesn't contain the community)."
|
|
);
|
|
|
|
SKIP: {
|
|
skip "No XML::Atom::Service/XML::Atom::Categories module installed.", 3
|
|
unless eval "use XML::Atom::Service; use XML::Atom::Categories; 1;";
|
|
|
|
my $service_document_xml = $r->response_content;
|
|
|
|
my $service = XML::Atom::Service->new( \$service_document_xml );
|
|
ok( $service, "Got service document." );
|
|
|
|
my @workspaces = $service->workspace;
|
|
is( scalar @workspaces, 2, "One workspace" );
|
|
isnt( $_->title, $nonmemberof_cu->user,
|
|
"Community you're not a member of doesn't appear in the service document." )
|
|
foreach @workspaces;
|
|
}
|
|
|
|
# community you are a member of
|
|
do_request( GET => $memberof_cu->atom_service_document, authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Got service document." );
|
|
like( $r->content_type, qr#^\Qapplication/atomsvc+xml\E#, "Service content type" );
|
|
|
|
SKIP: {
|
|
skip "No XML::Atom::Service/XML::Atom::Categories module installed.", 8
|
|
unless eval "use XML::Atom::Service; use XML::Atom::Categories; 1;";
|
|
|
|
my $service_document_xml = $r->response_content;
|
|
|
|
my $service = XML::Atom::Service->new( \$service_document_xml );
|
|
ok( $service, "Got service document." );
|
|
|
|
my @workspaces = $service->workspace;
|
|
is( scalar @workspaces, 2, "Personal journal and community as separate workspaces" );
|
|
|
|
# making assumptions that the second workspace is our community
|
|
my $memberof_cu_workspace = $workspaces[1];
|
|
is( $memberof_cu_workspace->title, $memberof_cu->user, "Workspace title" );
|
|
|
|
my @collections = $memberof_cu_workspace->collections;
|
|
is( scalar @collections, 1, "One collection" );
|
|
is( $collections[0]->title, "Entries", "Entries collection title" );
|
|
is( $collections[0]->href, $memberof_cu->atom_base . "/entries", "Entries collection uri" );
|
|
|
|
my @categories = $collections[0]->categories;
|
|
is( scalar @categories, 1, "One categories link" );
|
|
is(
|
|
$categories[0]->href,
|
|
$memberof_cu->atom_base . "/entries/tags",
|
|
"Categories collection uri"
|
|
);
|
|
}
|
|
|
|
note("Create an entry (community).");
|
|
my $title = "Community entry";
|
|
my $content = "Community entry content " . rand();
|
|
my $atom_entry = XML::Atom::Entry->new( Version => 1 );
|
|
$atom_entry->title($title);
|
|
$atom_entry->content($content);
|
|
|
|
# unauthenticated to community
|
|
do_request(
|
|
POST => $memberof_cu->atom_base . "/entries",
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Trying to post to community while unauthenticated." );
|
|
|
|
# community you don't have posting access to
|
|
do_request(
|
|
POST => $nonmemberof_cu->atom_base . "/entries",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED,
|
|
"Trying to post to community, but don't have posting access." );
|
|
|
|
# community you have posting access to
|
|
do_request(
|
|
POST => $memberof_cu->atom_base . "/entries",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_CREATED, "POSTed new entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
note("Double-check posted entry (community).");
|
|
$entry_obj = LJ::Entry->new( $memberof_cu, jitemid => 1 );
|
|
ok( $entry_obj, "got entry" );
|
|
ok( $entry_obj->valid, "entry is valid" );
|
|
is( $entry_obj->subject_raw, $title, "item has right title" );
|
|
is( $entry_obj->event_raw, $content, "item has right content" );
|
|
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $atom_entry_server->title,
|
|
content => $atom_entry_server->content->body,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig,
|
|
},
|
|
$memberof_cu
|
|
);
|
|
|
|
note("List entries (community).");
|
|
|
|
# unauthenticated to community
|
|
do_request( GET => $memberof_cu->atom_base . "/entries" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Entries feed needs authorization." );
|
|
|
|
# community you don't have posting access to
|
|
do_request( GET => $nonmemberof_cu->atom_base . "/entries", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Entries feed needs authorization." );
|
|
|
|
# community you have posting access to
|
|
do_request( GET => $memberof_cu->atom_base . "/entries", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Retrieved entry list" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
my $feed = XML::Atom::Feed->new( \$r->response_content );
|
|
my @entries = $feed->entries;
|
|
is( scalar @entries, 1, "Got entry from feed." );
|
|
|
|
note("Retrieve entry (community)");
|
|
|
|
# unauthenticated to community
|
|
do_request( GET => $memberof_cu->atom_base . "/entries/1" );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Retrieving entry needs authorization." );
|
|
|
|
# community you don't have posting access to
|
|
do_request( GET => $nonmemberof_cu->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "Retrieving entry needs authorization." );
|
|
|
|
# community you have posting access to
|
|
# retrieve (should succeed)
|
|
# edit (should succeed)
|
|
# delete (should succeed)
|
|
do_request( GET => $memberof_cu->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Retrieved entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $entry_obj->subject_raw,
|
|
content => $entry_obj->event_raw,
|
|
atom_id => $entry_obj->atom_id,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig
|
|
},
|
|
$memberof_cu
|
|
);
|
|
|
|
$atom_entry = XML::Atom::Entry->new( Version => 1 );
|
|
$title = "Edited Post";
|
|
$content = "Content of my post at " . rand();
|
|
$atom_entry->id( $atom_entry_server->id );
|
|
$atom_entry->title($title);
|
|
$atom_entry->content($content);
|
|
|
|
do_request(
|
|
PUT => $memberof_cu->atom_base . "/entries/1",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
|
|
is( $r->status, $r->HTTP_OK, "Edited entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
do_request( GET => $memberof_cu->atom_base . "/entries/1", authenticate => 1 );
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
check_entry(
|
|
$atom_entry_server,
|
|
{
|
|
id => $entry_obj->jitemid,
|
|
title => $title,
|
|
content => $content,
|
|
atom_id => $entry_obj->atom_id,
|
|
url => $entry_obj->url,
|
|
author => $u->name_orig,
|
|
},
|
|
$memberof_cu
|
|
);
|
|
|
|
do_request( DELETE => $memberof_cu->atom_base . "/entries/1", authenticate => 1 );
|
|
is( $r->status, $r->HTTP_OK, "Deleted entry" );
|
|
$entry_obj = LJ::Entry->new( $memberof_cu, jitemid => 1 );
|
|
isnt( $entry_obj->valid, "Entry confirmed deleted" );
|
|
|
|
note("Check what other people can do.");
|
|
|
|
# make another entry that other people can view/manipulate
|
|
do_request(
|
|
POST => $memberof_cu->atom_base . "/entries",
|
|
authenticate => 1,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
$atom_entry_server = XML::Atom::Entry->new( \$r->response_content );
|
|
$atom_entry = XML::Atom::Entry->new( Version => 1 );
|
|
$title = "Edited Post";
|
|
$content = "Content of my post at " . rand();
|
|
$atom_entry->id( $atom_entry_server->id );
|
|
$atom_entry->title($title);
|
|
$atom_entry->content($content);
|
|
|
|
# another community member
|
|
# retrieve (should fail)
|
|
# edit (should fail)
|
|
# delete (should fail)
|
|
do_request(
|
|
GET => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $another_u
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "You don't own this entry (another_u, get)" );
|
|
|
|
do_request(
|
|
PUT => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $another_u,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "You don't own this entry (another_u, edit)" );
|
|
|
|
do_request(
|
|
DELETE => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $another_u
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "You don't own this entry (another_u, delete)" );
|
|
|
|
# community admin
|
|
# retrieve (should succeed)
|
|
# edit (should fail)
|
|
# delete (should succeed)
|
|
do_request(
|
|
GET => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $admin_u
|
|
);
|
|
is( $r->status, $r->HTTP_OK, "Retrieved entry" );
|
|
is( $r->content_type, "application/atom+xml", "AtomAPI entry content type" );
|
|
|
|
do_request(
|
|
PUT => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $admin_u,
|
|
data => { input => $atom_entry->as_xml }
|
|
);
|
|
is( $r->status, $r->HTTP_UNAUTHORIZED, "You don't own this entry (admin_u, edit)" );
|
|
|
|
do_request(
|
|
DELETE => $memberof_cu->atom_base . "/entries/2",
|
|
authenticate => 1,
|
|
remote => $admin_u
|
|
);
|
|
is( $r->status, $r->HTTP_OK, "Deleted entry (admin_u, delete)" );
|
|
$entry_obj = LJ::Entry->new( $memberof_cu, jitemid => 2 );
|
|
isnt( $entry_obj->valid, "Entry confirmed deleted" );
|
|
}
|
|
|
|
done_testing();
|