Changeset 10176


Ignore:
Timestamp:
12/04/10 12:09:03 (2 years ago)
Author:
SvenDowideit
Message:

Item2321: add get list of topics in a web, and begin to make more explicit docco examples

add explicit test of using GET&POST with a new name to show shallow topic copy
POST web and post topic now do create a new resource - create web == same code as manage, view just initialises a new topic (and so will have problems with attachment meta

Location:
trunk/RestPlugin
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/RestPlugin/data/System/RestPlugin.txt

    r10129 r10176  
    1919 
    2020Initially supporting JSON encoding, it can be extended to anything - so long as symetrical serialisation/deserialisation are implemented using the (post foswiki 1.1) =Foswiki::Serialise= class. 
     21 
     22---+++ Resources 
     23---++++ Web 
     24| *Verb*   | *Implemented* | *URI*                                               | *Use* | 
     25| =GET=    |     yes       | =http://x61/bin/query/[{Webname}/]webs[.json]=      |  get web resource information, currently a list of subwebs to the resource (if no Webname is specified, list all webs)    | 
     26| =POST=   |     yes        | =http://x61/bin/query/[{Webname}/]webs[.json]=     |  create a new web in the uri's container web - parameters in payload as for the manage=createWeb     | 
     27| =PUT=    |     no        | =http://x61/bin/query/{Webname}/webs[.json]=        |  update a web resource (=nop= until define some web specific info, like permissions, settings etc), or maybe for renaming a web?)     | 
     28| =PATCH=  |     no        | =http://x61/bin/query/{Webname}/webs[.json]=        |  same as PUT?     | 
     29| =DELETE= |     no        | =http://x61/bin/query/{Webname}/webs[.json]=        |  delete web     | 
     30---++++ Topic 
     31| *Verb*   | *Implemented* | *URI*                                               | *Use* | 
     32| =GET=    |     yes       | =http://x61/bin/query/{Webname}/[{TopicName/}]topic[.json]=      |  get topic's meta (if no TopicName is specified, list of all topics in a web. (array of names only?))    | 
     33| =POST=   |     yes        | =http://x61/bin/query/{Webname}/topic[.json]=                   |  (TODO: might rejig to use UI::Manage::_create) create a new topic in the web container using the payload as topic data, and respecting AUTOINC name requests | 
     34| =PUT=    |     no        | =http://x61/bin/query/{Webname}/{TopicName}/topic[.json]=        |  update/create a topic resource completely with the payload - anything missing from the sent structure will be removed in the new revision, will not respect AUTOINC, and will use the topic name in the URI, not the payload. | 
     35| =PATCH=  |     yes       | =http://x61/bin/query/{Webname}/{TopicName}/topic[.json]=        |  update a topic using only a partial data - leaving unsent fields the same as n-1    | 
     36| =DELETE= |     no        | =http://x61/bin/query/{Webname}/{TopicName}/topic[.json]=        |  delete topic     | 
     37---++++ Attachments 
     38| *Verb*   | *Implemented* | *URI*                                               | *Use* | 
     39| =GET=    |     yes       | =http://x61/bin/query/{Webname}/{TopicName}/[{attachmentname}/]attachments[.json]=      |  get attachment resource information, currently a list of subwebs to the resource (if no Webname is specified, list all webs)    | 
     40| =POST=   |     no        | =http://x61/bin/query/{Webname}/{TopicName}/attachments[.json]=        |  create a new attachment ('this is essentially 'COPY', so might just be a consistency Alias)     | 
     41| =PUT=    |     no        | =http://x61/bin/query/{Webname}/{TopicName}/{attachmentname}/attachments[.json]=        |  update a attachment resource (=nop= until define some web specific info, like permissions, settings etc), or maybe for renaming a web?)     | 
     42| =PATCH=  |     no        | =http://x61/bin/query/{Webname}/{TopicName}/{attachmentname}/attachments[.json]=        |  same as PUT?     | 
     43| =DELETE= |     no        | =http://x61/bin/query/{Webname}/{TopicName}/{attachmentname}/attachments[.json]=        |  delete attachment     | 
     44 
     45---++++ unsupported requests 
     46you cannot make a =topic= or =attachment= element request on the root (eg =http://x61/f/bin/query/topic=), or an =attachment= request on a web. 
    2147 
    2248---+++ supported HTTP Request Types 
  • trunk/RestPlugin/lib/Foswiki/UI/Query.pm

    r10159 r10176  
    181181#I created a quick hack in the QueryAlgo::getField so that element 'hash' returned the meta object 
    182182#need to map topic==hash 
     183            my $webExists = Foswiki::Func::webExists($web); 
     184            my $topicExists = Foswiki::Func::topicExists( $web, $topic ); 
    183185            $baseObjectExists = 
    184               (       Foswiki::Func::webExists($web) 
    185                   and Foswiki::Func::topicExists( $web, $topic ) ); 
     186              ( $webExists and $topicExists ); 
    186187 
    187188            #$elementAlias = 'hash';# if ( $elementAlias eq 'topic' ); 
    188189            $query = "'$web.$topic'/$elementAlias"; 
     190 
     191            if (   ( ( $web eq '' ) and defined($topic) ) 
     192                or ( $webExists and not $topicExists ) ) 
     193            { 
     194 
     195              #perhaps its a request of the web container for a list of topics.. 
     196                my $testWeb = $web; 
     197                $testWeb .= '/' if ( length($testWeb) ); 
     198                $testWeb .= $topic if ( defined($topic) and ( $topic ne '' ) ); 
     199 
     200                if ( Foswiki::Func::webExists($testWeb) ) { 
     201                    $baseObjectExists = 1; 
     202                    $web              = $testWeb; 
     203                    $topic            = undef; 
     204                    $query            = "'$web'/$elementAlias"; 
     205 
     206                } 
     207            } 
    189208        } 
    190209        else { 
     
    229248    $accessType = 'VIEW'   if ( $request_method eq 'GET' ); 
    230249    $accessType = 'RENAME' if ( $request_method eq 'DELETE' ); 
     250    $accessType = 'ROOTCHANGE' 
     251      if (  ( $request_method ne 'GET' ) 
     252        and ( $web eq '' ) 
     253        and ( not defined($topic) ) ); 
    231254 
    232255    if ( not $topicObject->haveAccess($accessType) ) { 
     
    266289                or ( $elementAlias eq 'attachments' ) ) 
    267290            { 
    268                 my $evalParser = new Foswiki::Query::Parser(); 
    269                 my $querytxt   = $query; 
    270                 $querytxt =~ s/(topic)$/hash/; 
    271                 print STDERR 
     291                if ( ( $elementAlias eq 'topic' ) and not( defined($topic) ) ) { 
     292 
     293                #asking for a list of topics.. 
     294                #TODO: really bad idea - use a paging itr, or use a real query.. 
     295                    my @topicList = 
     296                      map { { '_topic' => $_ } } 
     297                      Foswiki::Func::getTopicList($web); 
     298                    $result = \@topicList; 
     299                } 
     300 
     301#                elsif (( $elementAlias eq 'attachments' ) and not(defined($topic))) { 
     302#                } 
     303                else { 
     304                    my $evalParser = new Foswiki::Query::Parser(); 
     305                    my $querytxt   = $query; 
     306                    $querytxt =~ s/(topic)$/hash/; 
     307                    print STDERR 
    272308"~~~~~~~~~~~~~~~~~~~~~~~topic: use query evaluate $querytxt\n"; 
    273                 my $node = $evalParser->parse($querytxt); 
    274  
    275                 $result = 
    276                   $node->evaluate( tom => $topicObject, data => $topicObject ); 
     309                    my $node = $evalParser->parse($querytxt); 
     310 
     311                    $result = $node->evaluate( 
     312                        tom  => $topicObject, 
     313                        data => $topicObject 
     314                    ); 
     315                } 
    277316            } 
    278317            elsif ( $elementAlias eq 'webs' ) { 
     
    311350            ASSERT( $requestPayload ne '' ) if DEBUG; 
    312351 
    313 #TODO: er, sorry, POST uri should be the web that the new topic will be made in... 
    314352            my $value = 
    315353              Foswiki::Serialise::deserialise( $session, $requestPayload, 
    316354                mapMimeType($requestContentType) ); 
    317355 
    318             #TODO: mmm, very much presuming we're creating a topic. 
    319             require Foswiki::UI::Save; 
    320             $topic = 
    321               Foswiki::UI::Save::expandAUTOINC( $session, $web, 
    322                 $value->{_topic} ); 
    323  
    324             #new topic... 
    325             $topicObject = Foswiki::Meta->new( $session, $web, $topic ); 
    326  
    327             copyFrom( $topicObject, $value ); 
    328             $topicObject->text( $value->{_text} ) 
    329               if ( defined( $value->{_text} ) ); 
    330             $topicObject->save(); 
    331  
    332             $result = $topicObject; 
     356            if ( $elementAlias eq 'topic' ) { 
     357                require Foswiki::UI::Save; 
     358                $topic = 
     359                  Foswiki::UI::Save::expandAUTOINC( $session, $web, 
     360                    $value->{_topic} ); 
     361#TODO: actually, consider using the UI::Manage::_create 
     362                #new topic... 
     363                $topicObject = Foswiki::Meta->new( $session, $web, $topic ); 
     364print STDERR "\n\nPOST: create new topic Meta (" 
     365      . $topicObject->web . ", " 
     366      . ( $topicObject->topic || '>UNDEF<' ) . ")\n\n\n"; 
     367 
     368                copyFrom( $topicObject, $value ); 
     369                $topicObject->text( $value->{_text} ) 
     370                  if ( defined( $value->{_text} ) ); 
     371                $topicObject->save(); 
     372                $result = $topicObject; 
     373                $res->pushHeader( 'Location', 
     374                    getResourceURI( $topicObject, 'topic' ) ); 
     375            } 
     376            elsif ( $elementAlias eq 'webs' ) { 
     377 
     378                #web creation - call UI::Manage::createWeb() 
     379                ASSERT( not defined($topic) ) if DEBUG; 
     380                $value->{newweb} = $web . '/' . $value->{newweb} 
     381                  if ( defined($web) ); 
     382                require Foswiki::UI::Manage; 
     383                my $newReq = new Foswiki::Request($value) 
     384                  ;    #use the payload to initialise the manage request 
     385                       #$newReq->path_info($url); 
     386                $newReq->method('manage'); 
     387                my $oldReq = $session->{request}; 
     388                $session->{request} = $newReq; 
     389                try { 
     390 
     391          #                    Foswiki::UI::Manage::_action_createweb($session); 
     392                  } catch Foswiki::OopsException with { 
     393                    my $e = shift; 
     394                    die 'whatever: '; 
     395                } 
     396                my @results = (); 
     397                my $webObject = 
     398                  Foswiki::Meta->load( $Foswiki::Plugins::SESSION, 
     399                    $value->{newweb} ); 
     400                push( @results, $webObject ); 
     401                $result = \@results; 
     402                $session->{request} = $oldReq; 
     403 
     404                $res->pushHeader( 'Location', 
     405                    getResourceURI( $webObject, 'webs' ) ); 
     406 
     407            } 
     408            else { 
     409                die 'not implemented'; 
     410            } 
    333411 
    334412    #if we created something and are returning it, and a uri for it, status=201 
     
    338416            $res->status('201 OK'); 
    339417 
    340 #TODO: yes, needs to detect what we're creating and change the element alias appropriatly. 
    341             $res->pushHeader( 'Location', 
    342                 getResourceURI( $topicObject, 'topic' ) ); 
    343418        } 
    344419        elsif ( $request_method eq 'DELETE' ) { 
     
    425500    #TODO: er, and what about attchments? 
    426501    #TODO: and allow mimetype to be added later 
    427     return Foswiki::Func::getScriptUrl( $meta->web, $meta->topic, 'query' ) 
     502    my ( $web, $topic ) = ( $meta->web, $meta->topic ); 
     503    $topic = undef if ( $elementAlias eq 'webs' ); 
     504    return Foswiki::Func::getScriptUrl( $web, $topic, 'query' ) 
    428505      . "/$elementAlias"; 
    429506} 
  • trunk/RestPlugin/test/unit/RestPlugin/RestPluginCurlTests.pm

    r10159 r10176  
    112112    return ( $result, $data ); 
    113113} 
    114  
    115 sub addToResultHash { 
    116     my ( $timestamp, $type, $text, $hash ) = @_; 
    117  
    118     $hash->{$type} .= "$timestamp $type $text\n"; 
    119     if ( $type eq '<' ) {    #response header 
    120                              #HTTP/1.1 200 OK 
    121         if ( $text =~ /HTTP\/1.1\s(\d*)\s(.*)/ ) { 
    122             $hash->{HTTP_RESPONSE_STATUS}      = $1; 
    123             $hash->{HTTP_RESPONSE_STATUS_TEXT} = $2; 
    124         } 
    125  
    126         #X-Foswiki-Rest-Query: 'Main.SvenDowideit'/topic etc 
    127         if ( $text =~ /(.*):\s*(.*)/ ) { 
    128             $hash->{$1} = $2; 
    129         } 
    130     } 
    131  
    132     return ''; 
    133 } 
    134  
    135 sub testGET { 
    136     my $this = shift; 
    137  
    138     { 
    139  
    140         #/Main/WebHome/topic.json 
    141         my ( $replytext, $extraHash ) = $this->callCurl( 'GET', 'text/json', '', 
    142             Foswiki::Func::getScriptUrl( undef, undef, 'query' ) 
    143               . '/Main/WebHome/topic.json' ); 
    144  
    145         #print STDERR $replytext; 
    146         my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
    147         my ( $meta, $text ) = Foswiki::Func::readTopic( 'Main', 'WebHome' ); 
    148         $this->assert_deep_equals( $fromJSON, 
    149             Foswiki::Serialise::convertMeta($meta) ); 
    150         $this->assert_equals( '200', $extraHash->{HTTP_RESPONSE_STATUS} ); 
    151         $this->assert_equals( 'OK',  $extraHash->{HTTP_RESPONSE_STATUS_TEXT} ); 
    152         $this->assert_equals( "'Main.WebHome'/topic", 
    153             $extraHash->{'X-Foswiki-Rest-Query'} ); 
    154  
    155         #TODO: test the other values we're returning 
    156     } 
    157  
    158     { 
    159  
    160         #/Main/TopicDoesNotTexit/topic.json 
    161         my ( $replytext, $extraHash ) = $this->callCurl( 'GET', 'text/json', '', 
    162             Foswiki::Func::getScriptUrl( undef, undef, 'query' ) 
    163               . '/Main/TopicDoesNotTexit/topic.json' ); 
    164  
    165         #no payload 
    166         #        $this->assert_deep_equals( $fromJSON, 
    167         #            Foswiki::Serialise::convertMeta($meta) ); 
    168         $this->assert_equals( '404', $extraHash->{HTTP_RESPONSE_STATUS} ); 
    169         $this->assert_equals( 'Not Found', 
    170             $extraHash->{HTTP_RESPONSE_STATUS_TEXT} ); 
    171         $this->assert_equals( 
    172             undef, 
    173  
    174             #"'Main.TopicDoesNotTexit'/topic", 
    175             $extraHash->{'X-Foswiki-Rest-Query'} 
    176         ); 
    177  
    178         #TODO: test the other values we're returning 
    179     } 
    180  
    181 } 
    182  
    183 sub testPATCH { 
    184     my $this = shift; 
    185  
    186    #THIS MUST FAIL, guest should never have the ability to change System.WebHome 
    187    #/System/WebHome/topic.json 
    188     $this->runTest( 
    189         'PATCH', 
    190         'text/json', 
    191         '{"_text": "Some text"}', 
    192         'System', 
    193         'WebHome', 
    194         'topic', 'json', 
    195         { 
    196             HTTP_RESPONSE_STATUS      => '401', 
    197             HTTP_RESPONSE_STATUS_TEXT => 'Authorization Required', 
    198             'X-Foswiki-Rest-Query'    => undef, 
    199         } 
    200     ); 
    201  
    202     $this->runTest( 
    203         'PATCH', 
    204         'text/json', 
    205         '{"_text": "Some text"}', 
    206         'Sandbox', 
    207         'TestTopicAUTOINC001', 
    208         'topic', 'json', 
    209         { 
    210             HTTP_RESPONSE_STATUS      => '404', 
    211             HTTP_RESPONSE_STATUS_TEXT => 'Not Found', 
    212             'X-Foswiki-Rest-Query'    => undef, 
    213         } 
    214     ); 
    215  
    216 #$this->{test_web}, "Improvement2" 
    217 #ER POOP. the test web is created with the wrong filesystem user, so can't be accessed by the web server (in some setups.) 
    218     $this->runTest( 
    219         'PATCH', 
    220         'text/json', 
    221         '{"_text": "Some text"}', 
    222         $this->{test_web}, 
    223         'Improvement2', 
    224         'topic', 'json', 
    225         { 
    226             HTTP_RESPONSE_STATUS => '500', 
    227  
    228 #            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
    229 #            'X-Foswiki-Rest-Query'    => '\''.$this->{test_web}.'.Improvement2\'/topic', 
    230         } 
    231     ); 
    232  
    233 #TODO: {rest_test_web}  needs to be created using curl - so that the webserver permissions are useable. 
    234     return; 
    235  
    236     #COPY 
    237     #$this->{rest_test_web}, "Improvement2" 
    238     $this->runTest( 
    239         'PATCH', 
    240         'text/json', 
    241         '{"_topic": "ACopyOfImprovement2"}', 
    242         $this->{rest_test_web}, 
    243         'Improvement2', 
    244         'topic', 'json', 
    245         { 
    246             HTTP_RESPONSE_STATUS      => '200', 
    247             HTTP_RESPONSE_STATUS_TEXT => 'OK', 
    248             'X-Foswiki-Rest-Query'    => '\'' 
    249               . $this->{rest_test_web} 
    250               . '.ACopyOfImprovement2\'/topic', 
    251         } 
    252     ); 
    253 } 
    254  
    255 sub test_attachmentsProjectLogos { 
    256     my $this = shift; 
    257  
    258     #requesting a list of attachments in the 'container' System.ProjectLogos 
    259     #/System/ProjectLogos/attachment.json 
    260     $this->runTest( 
    261         'GET', 
    262         'text/json', 
    263         '', 'System', 
    264         'ProjectLogos', 
    265         'attachments', 
    266         'json', 
    267         { 
    268             HTTP_RESPONSE_STATUS      => '200', 
    269             HTTP_RESPONSE_STATUS_TEXT => 'OK', 
    270             'X-Foswiki-Rest-Query'    => '\'System.ProjectLogos\'/attachments', 
    271         }, 
    272 '[{"attachment":"favicon.ico","version":"1","date":"1227691956","name":"favicon.ico","path":"favicon.ico","attr":"","size":"1150","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-badge.png","version":"2","date":"1227691956","name":"foswiki-badge.gif","path":"foswiki-badge.png","attr":"","size":"4807","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-logo.gif","version":"2","date":"1227691994","name":"foswiki-logo.gif","path":"foswiki-logo.gif","attr":"","size":"7537","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-logo.xcf","version":"1","date":"1227691956","name":"foswiki-logo.xcf","path":"foswiki-logo.xcf","attr":"","size":"45514","user":"ProjectContributor"}]' 
    273     ); 
    274 } 
    275  
    276 sub test_attachmentsWebHome { 
    277     my $this = shift; 
    278  
    279     #no attachments on topic 
    280     $this->runTest( 
    281         'GET', 
    282         'text/json', 
    283         '', 'System', 
    284         'WebHome', 
    285         'attachments', 
    286         'json', 
    287         { 
    288             HTTP_RESPONSE_STATUS      => '200', 
    289             HTTP_RESPONSE_STATUS_TEXT => 'OK', 
    290             'X-Foswiki-Rest-Query'    => '\'System.WebHome\'/attachments', 
    291         }, 
    292         '' 
    293     ); 
    294 } 
    295 sub test_attachments_modify { 
    296     my $this = shift; 
    297      
    298      
    299     #$this->{test_web}, 'SomeAttachments', 
    300     $this->runTest( 
    301         'GET', 
    302         'text/json', 
    303         '',  
    304         $this->{test_web},  
    305         'SomeAttachments', 
    306         'attachments', 
    307         'json', 
    308         { 
    309             HTTP_RESPONSE_STATUS      => '200', 
    310             HTTP_RESPONSE_STATUS_TEXT => 'OK', 
    311             'X-Foswiki-Rest-Query'    => '\'TemporaryRestPluginCurlTestsTestWebRestPluginCurlTests.SomeAttachments\'/attachments', 
    312         }, 
    313         '' 
    314     ); 
    315 } 
    316  
    317114 
    318115sub runTest { 
     
    366163} 
    367164 
     165 
     166sub addToResultHash { 
     167    my ( $timestamp, $type, $text, $hash ) = @_; 
     168 
     169    $hash->{$type} .= "$timestamp $type $text\n"; 
     170    if ( $type eq '<' ) {    #response header 
     171                             #HTTP/1.1 200 OK 
     172        if ( $text =~ /HTTP\/1.1\s(\d*)\s(.*)/ ) { 
     173            $hash->{HTTP_RESPONSE_STATUS}      = $1; 
     174            $hash->{HTTP_RESPONSE_STATUS_TEXT} = $2; 
     175        } 
     176 
     177        #X-Foswiki-Rest-Query: 'Main.SvenDowideit'/topic etc 
     178        if ( $text =~ /(.*):\s*(.*)/ ) { 
     179            $hash->{$1} = $2; 
     180        } 
     181    } 
     182 
     183    return ''; 
     184} 
     185 
     186sub testGET_topiclist { 
     187    my $this = shift; 
     188 
     189    {#(list of topics...) 
     190        #/Main/topic.json 
     191        my ( $replytext, $extraHash ) = $this->callCurl( 'GET', 'text/json', '', 
     192            Foswiki::Func::getScriptUrl( undef, undef, 'query' ) 
     193              . '/Main/topic.json' ); 
     194 
     195        #print STDERR $replytext; 
     196        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     197        my @topicList = map { {'_topic'=> $_} } Foswiki::Func::getTopicList('Main'); 
     198        $this->assert_deep_equals( $fromJSON, 
     199            \@topicList); 
     200        $this->assert_equals( '200', $extraHash->{HTTP_RESPONSE_STATUS} ); 
     201        $this->assert_equals( 'OK',  $extraHash->{HTTP_RESPONSE_STATUS_TEXT} ); 
     202        $this->assert_equals( "'Main'/topic", 
     203            $extraHash->{'X-Foswiki-Rest-Query'} ); 
     204 
     205        #TODO: test the other values we're returning 
     206    } 
     207 
     208} 
     209 
     210sub testGET { 
     211    my $this = shift; 
     212    { 
     213        #/Main/WebHome/topic.json 
     214        my ( $replytext, $extraHash ) = $this->callCurl( 'GET', 'text/json', '', 
     215            Foswiki::Func::getScriptUrl( undef, undef, 'query' ) 
     216              . '/Main/WebHome/topic.json' ); 
     217 
     218        #print STDERR $replytext; 
     219        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     220        my ( $meta, $text ) = Foswiki::Func::readTopic( 'Main', 'WebHome' ); 
     221        $this->assert_deep_equals( $fromJSON, 
     222            Foswiki::Serialise::convertMeta($meta) ); 
     223        $this->assert_equals( '200', $extraHash->{HTTP_RESPONSE_STATUS} ); 
     224        $this->assert_equals( 'OK',  $extraHash->{HTTP_RESPONSE_STATUS_TEXT} ); 
     225        $this->assert_equals( "'Main.WebHome'/topic", 
     226            $extraHash->{'X-Foswiki-Rest-Query'} ); 
     227 
     228        #TODO: test the other values we're returning 
     229    } 
     230 
     231    { 
     232 
     233        #/Main/TopicDoesNotTexit/topic.json 
     234        my ( $replytext, $extraHash ) = $this->callCurl( 'GET', 'text/json', '', 
     235            Foswiki::Func::getScriptUrl( undef, undef, 'query' ) 
     236              . '/Main/TopicDoesNotTexit/topic.json' ); 
     237 
     238        #no payload 
     239        #        $this->assert_deep_equals( $fromJSON, 
     240        #            Foswiki::Serialise::convertMeta($meta) ); 
     241        $this->assert_equals( '404', $extraHash->{HTTP_RESPONSE_STATUS} ); 
     242        $this->assert_equals( 'Not Found', 
     243            $extraHash->{HTTP_RESPONSE_STATUS_TEXT} ); 
     244        $this->assert_equals( 
     245            undef, 
     246 
     247            #"'Main.TopicDoesNotTexit'/topic", 
     248            $extraHash->{'X-Foswiki-Rest-Query'} 
     249        ); 
     250 
     251        #TODO: test the other values we're returning 
     252    } 
     253 
     254} 
     255 
     256sub testPATCH { 
     257    my $this = shift; 
     258 
     259   #THIS MUST FAIL, guest should never have the ability to change System.WebHome 
     260   #/System/WebHome/topic.json 
     261    $this->runTest( 
     262        'PATCH', 
     263        'text/json', 
     264        '{"_text": "Some text"}', 
     265        'System', 
     266        'WebHome', 
     267        'topic', 'json', 
     268        { 
     269            HTTP_RESPONSE_STATUS      => '401', 
     270            HTTP_RESPONSE_STATUS_TEXT => 'Authorization Required', 
     271            'X-Foswiki-Rest-Query'    => undef, 
     272        } 
     273    ); 
     274 
     275    $this->runTest( 
     276        'PATCH', 
     277        'text/json', 
     278        '{"_text": "Some text"}', 
     279        'Sandbox', 
     280        'TestTopicAUTOINC001', 
     281        'topic', 'json', 
     282        { 
     283            HTTP_RESPONSE_STATUS      => '404', 
     284            HTTP_RESPONSE_STATUS_TEXT => 'Not Found', 
     285            'X-Foswiki-Rest-Query'    => undef, 
     286        } 
     287    ); 
     288 
     289#$this->{test_web}, "Improvement2" 
     290#ER POOP. the test web is created with the wrong filesystem user, so can't be accessed by the web server (in some setups.) 
     291    $this->runTest( 
     292        'PATCH', 
     293        'text/json', 
     294        '{"_text": "Some text"}', 
     295        $this->{test_web}, 
     296        'Improvement2', 
     297        'topic', 'json', 
     298        { 
     299            HTTP_RESPONSE_STATUS => '500', 
     300 
     301#            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
     302#            'X-Foswiki-Rest-Query'    => '\''.$this->{test_web}.'.Improvement2\'/topic', 
     303        } 
     304    ); 
     305 
     306#TODO: {rest_test_web}  needs to be created using curl - so that the webserver permissions are useable. 
     307    return; 
     308 
     309    #COPY 
     310    #$this->{rest_test_web}, "Improvement2" 
     311    $this->runTest( 
     312        'PATCH', 
     313        'text/json', 
     314        '{"_topic": "ACopyOfImprovement2"}', 
     315        $this->{rest_test_web}, 
     316        'Improvement2', 
     317        'topic', 'json', 
     318        { 
     319            HTTP_RESPONSE_STATUS      => '200', 
     320            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
     321            'X-Foswiki-Rest-Query'    => '\'' 
     322              . $this->{rest_test_web} 
     323              . '.ACopyOfImprovement2\'/topic', 
     324        } 
     325    ); 
     326} 
     327 
     328sub test_attachmentsProjectLogos { 
     329    my $this = shift; 
     330 
     331    #requesting a list of attachments in the 'container' System.ProjectLogos 
     332    #/System/ProjectLogos/attachment.json 
     333    $this->runTest( 
     334        'GET', 
     335        'text/json', 
     336        '', 'System', 
     337        'ProjectLogos', 
     338        'attachments', 
     339        'json', 
     340        { 
     341            HTTP_RESPONSE_STATUS      => '200', 
     342            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
     343            'X-Foswiki-Rest-Query'    => '\'System.ProjectLogos\'/attachments', 
     344        }, 
     345'[{"attachment":"favicon.ico","version":"1","date":"1227691956","name":"favicon.ico","path":"favicon.ico","attr":"","size":"1150","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-badge.png","version":"2","date":"1227691956","name":"foswiki-badge.gif","path":"foswiki-badge.png","attr":"","size":"4807","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-logo.gif","version":"2","date":"1227691994","name":"foswiki-logo.gif","path":"foswiki-logo.gif","attr":"","size":"7537","comment":"","user":"ProjectContributor"},{"attachment":"foswiki-logo.xcf","version":"1","date":"1227691956","name":"foswiki-logo.xcf","path":"foswiki-logo.xcf","attr":"","size":"45514","user":"ProjectContributor"}]' 
     346    ); 
     347} 
     348 
     349sub test_attachmentsWebHome { 
     350    my $this = shift; 
     351 
     352    #no attachments on topic 
     353    $this->runTest( 
     354        'GET', 
     355        'text/json', 
     356        '', 'System', 
     357        'WebHome', 
     358        'attachments', 
     359        'json', 
     360        { 
     361            HTTP_RESPONSE_STATUS      => '200', 
     362            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
     363            'X-Foswiki-Rest-Query'    => '\'System.WebHome\'/attachments', 
     364        }, 
     365        '' 
     366    ); 
     367} 
     368sub test_attachments_modify { 
     369    my $this = shift; 
     370     
     371    #$this->{test_web}, 'SomeAttachments', 
     372    $this->runTest( 
     373        'GET', 
     374        'text/json', 
     375        '',  
     376        $this->{test_web},  
     377        'SomeAttachments', 
     378        'attachments', 
     379        'json', 
     380        { 
     381            HTTP_RESPONSE_STATUS      => '200', 
     382            HTTP_RESPONSE_STATUS_TEXT => 'OK', 
     383            'X-Foswiki-Rest-Query'    => '\'TemporaryRestPluginCurlTestsTestWebRestPluginCurlTests.SomeAttachments\'/attachments', 
     384        }, 
     385        '' 
     386    ); 
     387#TODO: boom, and here again, I need to be able to create a web, or delete a topic.. 
     388} 
     389 
    3683901; 
  • trunk/RestPlugin/test/unit/RestPlugin/RestPluginTests.pm

    r10158 r10176  
    5151 
    5252sub call_UI_query { 
    53     my ( $this, $url, $action, $params ) = @_; 
     53    my ( $this, $url, $action, $params, $cuid ) = @_; 
    5454    my $query = new Unit::Request($params); 
    5555    $query->path_info($url); 
    5656    $query->method($action); 
    5757    my $sess = $Foswiki::Plugins::SESSION; 
    58  
    59     print STDERR "=-=- the user running the UI: " 
    60       . $this->{test_user_login} . "\n"; 
     58    $cuid = $this->{test_user_login} unless defined($cuid); 
     59 
     60    print STDERR "=-=- the user running the UI: " . $cuid . "\n"; 
    6161    $fatwilly = new Foswiki( $this->{test_user_login}, $query ); 
    6262 
     
    399399    my $sendJSON = JSON::to_json($fromJSON); 
    400400    ( $replytext, $hdr ) = 
    401       $this->call_UI_query( '/' . $this->{test_web} . '/webs.json', 
     401      $this->call_UI_query( '/' . $this->{test_web} . '/topic.json', 
    402402        'POST', { 'POSTDATA' => $sendJSON } ); 
    403403 
     
    461461    my $sendJSON = JSON::to_json($fromJSON); 
    462462    ( $replytext, $hdr ) = 
    463       $this->call_UI_query( '/' . $this->{test_web} . '/webs.json', 
     463      $this->call_UI_query( '/' . $this->{test_web} . '/topic.json', 
    464464        'POST', { 'POSTDATA' => $sendJSON } ); 
    465465 
     
    489489} 
    490490 
     491sub test_copy_topic { 
     492    my $this = shift; 
     493 
     494#TODO: this is a dumb blind copy, where we even copy attachment meta that is not valid for this new topic. 
     495 
     496    { 
     497        my ( $replytext, $hdr ) = $this->call_UI_query( 
     498            '/' . $this->{test_web} . '/Improvement2/topic.json', 
     499            'GET', {} ); 
     500        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     501        $fromJSON->{_topic} = 'CopyOfimprovement2'; 
     502 
     503        $this->assert( 
     504            not Foswiki::Func::topicExists( 
     505                $this->{test_web}, 'CopyOfimprovement2' 
     506            ) 
     507        ); 
     508        my $sendJSON = JSON::to_json($fromJSON); 
     509         
     510        sleep(1); 
     511 
     512        #POST to the web.. 
     513        ( $replytext, $hdr ) = 
     514          $this->call_UI_query( '/' . $this->{test_web} . '/topic.json', 
     515            'POST', { 'POSTDATA' => $sendJSON } ); 
     516 
     517        $this->assert( 
     518            Foswiki::Func::topicExists( 
     519                $this->{test_web}, 'CopyOfimprovement2' 
     520            ) 
     521        ); 
     522        my ( $meta, $text ) = 
     523          Foswiki::Func::readTopic( $this->{test_web}, 'CopyOfimprovement2' ); 
     524           
     525        #amend $fromJSON's time&author 
     526        $sendJSON =~ s/BaseUserMapping_666/scum/g; 
     527        $sendJSON =~ s/$fromJSON->{TOPICINFO}[0]->{date}/$meta->{TOPICINFO}[0]->{date}/g; 
     528        $this->assert_deep_equals( Foswiki::Serialise::convertMeta($meta), 
     529            JSON::from_json($sendJSON, { allow_nonref => 1 }) ); 
     530    } 
     531} 
     532 
     533sub test_create_web { 
     534    my $this = shift; 
     535 
     536    #TODO: make sure the Location and other Headers are correct.. 
     537    { 
     538        my $newWeb = $this->{test_web} . 'REST'; 
     539        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     540 
     541        #create  web using _default 
     542        my $sendJSON = JSON::to_json( 
     543            { 
     544                baseweb    => '_default', 
     545                newweb     => $newWeb, 
     546                webbgcolor => '#ff2222', 
     547                websummary => 'web created by query REST API' 
     548            } 
     549        ); 
     550        my ( $replytext, $hdr ) = 
     551          $this->call_UI_query( '/webs.json?copy', 'POST', 
     552            { 'POSTDATA' => $sendJSON }, 
     553            'BaseUserMapping_333' ); 
     554        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     555 
     556        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     557        $this->assert( '#ff2222', 
     558            Foswiki::Func::getPreferencesValue( 'WEBBGCOLOR', $newWeb ) ); 
     559        $this->assert( 'web created by query REST API', 
     560            Foswiki::Func::getPreferencesValue( 'WEBSUMMARY', $newWeb ) ); 
     561    } 
     562 
     563    { 
     564        my $newWeb = 'Sandbox/' . $this->{test_web} . 'REST'; 
     565        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     566 
     567        #create  web using _default 
     568        my $sendJSON = JSON::to_json( 
     569            { 
     570                baseweb    => '_default', 
     571                newweb     => $newWeb, 
     572                webbgcolor => '#22ff22', 
     573                websummary => 'subweb created by query REST API' 
     574            } 
     575        ); 
     576        my ( $replytext, $hdr ) = 
     577          $this->call_UI_query( '/webs.json?copy', 'POST', 
     578            { 'POSTDATA' => $sendJSON }, 
     579            'BaseUserMapping_333' ); 
     580        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     581 
     582        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     583        $this->assert( '#22ff22', 
     584            Foswiki::Func::getPreferencesValue( 'WEBBGCOLOR', $newWeb ) ); 
     585        $this->assert( 'subweb created by query REST API', 
     586            Foswiki::Func::getPreferencesValue( 'WEBSUMMARY', $newWeb ) ); 
     587    } 
     588    {    #this one the newWeb should become a subweb of the uri web.. 
     589        my $nestedWeb = $this->{test_web} . 'Again'; 
     590        my $newWeb    = 'Sandbox/' . $nestedWeb; 
     591        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     592 
     593        #create  web using _default 
     594        my $sendJSON = JSON::to_json( 
     595            { 
     596                baseweb    => '_default', 
     597                newweb     => $nestedWeb, 
     598                webbgcolor => '#22ff22', 
     599                websummary => 'another subweb created by query REST API' 
     600            } 
     601        ); 
     602        my ( $replytext, $hdr ) = 
     603          $this->call_UI_query( '/Sandbox/webs.json?copy', 'POST', 
     604            { 'POSTDATA' => $sendJSON }, 
     605            'BaseUserMapping_333' ); 
     606        my $fromJSON = JSON::from_json( $replytext, { allow_nonref => 1 } ); 
     607 
     608        $this->assert( not Foswiki::Func::webExists($newWeb) ); 
     609        $this->assert( '#22ff22', 
     610            Foswiki::Func::getPreferencesValue( 'WEBBGCOLOR', $newWeb ) ); 
     611        $this->assert( 'another subweb created by query REST API', 
     612            Foswiki::Func::getPreferencesValue( 'WEBSUMMARY', $newWeb ) ); 
     613    } 
     614} 
     615 
    4916161; 
Note: See TracChangeset for help on using the changeset viewer.