001package org.w3.ldp.testsuite.test; 002 003import com.hp.hpl.jena.rdf.model.Model; 004import com.hp.hpl.jena.rdf.model.Property; 005import com.hp.hpl.jena.rdf.model.RDFNode; 006import com.hp.hpl.jena.rdf.model.Resource; 007import com.hp.hpl.jena.rdf.model.ResourceFactory; 008import com.hp.hpl.jena.rdf.model.StmtIterator; 009import com.hp.hpl.jena.rdf.model.Statement; 010import com.jayway.restassured.response.Response; 011 012import org.apache.http.HttpStatus; 013import org.testng.annotations.BeforeClass; 014import org.testng.annotations.Optional; 015import org.testng.annotations.Parameters; 016import org.testng.annotations.Test; 017import org.w3.ldp.testsuite.LdpTestSuite; 018import org.w3.ldp.testsuite.annotations.SpecTest; 019import org.w3.ldp.testsuite.annotations.SpecTest.METHOD; 020import org.w3.ldp.testsuite.annotations.SpecTest.STATUS; 021import org.w3.ldp.testsuite.exception.SkipException; 022import org.w3.ldp.testsuite.http.LdpPreferences; 023import org.w3.ldp.testsuite.mapper.RdfObjectMapper; 024import org.w3.ldp.testsuite.vocab.LDP; 025 026import java.io.IOException; 027 028import static org.testng.Assert.assertTrue; 029import static org.w3.ldp.testsuite.http.HttpHeaders.ACCEPT; 030import static org.w3.ldp.testsuite.http.HttpHeaders.LINK_REL_TYPE; 031import static org.w3.ldp.testsuite.http.HttpHeaders.PREFER; 032import static org.w3.ldp.testsuite.http.LdpPreferences.PREFER_MINIMAL_CONTAINER; 033import static org.w3.ldp.testsuite.http.MediaTypes.TEXT_TURTLE; 034 035public class IndirectContainerTest extends CommonContainerTest { 036 037 private String indirectContainer; 038 private Property insertedContentRelationProperty = null; 039 040 @Parameters({"indirectContainer", "auth"}) 041 public IndirectContainerTest(@Optional String indirectContainer, @Optional String auth) throws IOException { 042 super(auth); 043 this.indirectContainer = indirectContainer; 044 } 045 046 @BeforeClass(alwaysRun = true) 047 public void hasIndirectContainer() { 048 if (indirectContainer == null) { 049 throw new SkipException(Thread.currentThread().getStackTrace()[1].getMethodName(), 050 "No indirectContainer parameter provided in testng.xml. Skipping ldp:IndirectContainer tests.", 051 skipLog); 052 } 053 054 try { 055 setInsertedContentRelation(); 056 } catch(Exception ignore) {} 057 } 058 059 // TODO implement tests, signatures are from LDP spec 060 @Test( 061 groups = {MUST}, 062 description = "LDP servers exposing LDPCs MUST advertise their " 063 + "LDP support by exposing a HTTP Link header with a " 064 + "target URI matching the type of container (see below) " 065 + "the server supports, and a link relation type of type " 066 + "(that is, rel='type') in all responses to requests made " 067 + "to the LDPC's HTTP Request-URI.") 068 @SpecTest( 069 specRefUri = LdpTestSuite.SPEC_URI + "#ldpc-linktypehdr", 070 testMethod = METHOD.AUTOMATED, 071 approval = STATUS.WG_APPROVED, 072 comment = "Covers only part of the specification requirement. " 073 + "DirectContainerTest.testHttpLinkHeader and " 074 + "BasicContainerTest.testContainerSupportsHttpLinkHeader " 075 + "covers the rest.") 076 public void testContainerSupportsHttpLinkHeader() { 077 Response response = buildBaseRequestSpecification().header(ACCEPT, TEXT_TURTLE) 078 .expect().statusCode(HttpStatus.SC_OK).when() 079 .get(indirectContainer); 080 assertTrue( 081 containsLinkHeader( 082 indirectContainer, 083 LINK_REL_TYPE, 084 LDP.IndirectContainer.stringValue(), 085 indirectContainer, 086 response 087 ), 088 "LDP DirectContainers must advertise their LDP support by exposing a HTTP Link header with a URI matching <" 089 + LDP.IndirectContainer.stringValue() 090 + "> and rel='type'" 091 ); 092 } 093 094 @Test( 095 groups = {MUST}, 096 enabled = false, 097 description = "Each LDP Indirect Container MUST also be a conforming " 098 + "LDP Direct Container in section 5.4 Direct along " 099 + "the following restrictions.") 100 @SpecTest( 101 specRefUri = LdpTestSuite.SPEC_URI + "#ldpic-are-ldpcs", 102 testMethod = METHOD.NOT_IMPLEMENTED, 103 approval = STATUS.WG_PENDING) 104 public void testConformsIcLdpContainer() { 105 // TODO: Impl testConformsIcLdpContainer 106 } 107 108 @Test( 109 groups = {MUST}, 110 enabled = true, 111 description = "LDP Indirect Containers MUST contain exactly one " 112 + "triple whose subject is the LDPC URI, whose predicate " 113 + "is ldp:insertedContentRelation, and whose object ICR " 114 + "describes how the member-derived-URI in the container's " 115 + "membership triples is chosen.") 116 @SpecTest( 117 specRefUri = LdpTestSuite.SPEC_URI + "#ldpic-indirectmbr", 118 testMethod = METHOD.AUTOMATED, 119 approval = STATUS.WG_PENDING) 120 public void testContainerHasInsertedContentRelation() { 121 Response getResponse = buildBaseRequestSpecification() 122 .header(ACCEPT, TEXT_TURTLE) 123 .header(PREFER, include(PREFER_MINIMAL_CONTAINER)) 124 .expect() 125 .statusCode(HttpStatus.SC_OK) 126 .when() 127 .get(indirectContainer); 128 Model containerModel = getResponse.as(Model.class, new RdfObjectMapper(indirectContainer)); 129 Resource container = containerModel.getResource(indirectContainer); 130 Property insertedContentRelation = ResourceFactory.createProperty(LDP.insertedContentRelation.stringValue()); 131 132 assertTrue( 133 container.hasProperty(insertedContentRelation), 134 "Container <" 135 + indirectContainer 136 + "> does not have a triple with the LDPC URI as the subject and ldp:insertedContentRelation as the predicate." 137 ); 138 139 StmtIterator stmtIterator = container.listProperties(insertedContentRelation); 140 RDFNode node = stmtIterator.next().getObject(); 141 142 assertTrue( 143 node.isURIResource(), 144 "The property with predicate ldp:insertedContentRelation, doesn't point to an RDF Object." 145 ); 146 147 assertTrue( 148 ! stmtIterator.hasNext(), 149 "Container <" 150 + indirectContainer 151 + "> has more than one triple with the LDPC URI as the subject and ldp:insertedContentRelation as the predicate." 152 ); 153 } 154 155 @Test( 156 groups = {MUST}, 157 enabled = false, 158 description = "LDPCs whose ldp:insertedContentRelation triple has an " 159 + "object other than ldp:MemberSubject and that create new " 160 + "resources MUST add a triple to the container whose subject is " 161 + "the container's URI, whose predicate is ldp:contains, and whose " 162 + "object is the newly created resource's URI (which will be " 163 + "different from the member-derived URI in this case). This " 164 + "ldp:contains triple can be the only link from the container to the " 165 + "newly created resource in certain cases.") 166 @SpecTest( 167 specRefUri = LdpTestSuite.SPEC_URI + "#ldpic-post-indirectmbrrel", 168 testMethod = METHOD.NOT_IMPLEMENTED, 169 approval = STATUS.WG_PENDING) 170 public void testPostResource() { 171 // TODO: Impl testPostResource 172 } 173 174 private void setInsertedContentRelation() { 175 Response getResponse = buildBaseRequestSpecification() 176 .header(ACCEPT, TEXT_TURTLE) 177 .header(PREFER, include(LdpPreferences.PREFER_MINIMAL_CONTAINER)) 178 .when() 179 .get(indirectContainer); 180 181 Model containerModel = getResponse.as(Model.class, new RdfObjectMapper(indirectContainer)); 182 Resource container = containerModel.getResource(indirectContainer); 183 Property insertedContentRelation = containerModel.getProperty(LDP.insertedContentRelation.stringValue()); 184 185 if ( ! container.hasProperty(insertedContentRelation) ) return; 186 187 Statement statement = container.getProperty(insertedContentRelation); 188 RDFNode node = statement.getObject(); 189 190 if ( ! node.isURIResource() ) return; 191 192 String propertyURI = node.asResource().getURI(); 193 insertedContentRelationProperty = ResourceFactory.createProperty(propertyURI); 194 } 195 196 @Override 197 protected String getResourceUri() { 198 return indirectContainer; 199 } 200 201 @Override 202 protected Model getDefaultModel() { 203 Model model = super.getDefaultModel(); 204 205 if ( insertedContentRelationProperty == null ) return model; 206 207 Resource resource = model.getResource(""); 208 resource.addProperty(insertedContentRelationProperty, model.createResource("#me")); 209 return model; 210 } 211 212}