<!-- a resource descriptor to more-or-less safely test a couple of operations
-->

<resource resdir="__system" schema="tests">
	<service id="coredump" limitTo="gavoadmin">
		<pythonCore>
			<coreProc>
				<code>
					import os, signal
					os.kill(os.getpid(), signal.SIGSEGV)
				</code>
			</coreProc>
		</pythonCore>
	</service>

	<fixedQueryCore id="resetcore" writable="True"
		query="delete from tests.files where name='c'">
		<outputTable/>
	</fixedQueryCore>

	<service id="reset" core="resetcore">
		<meta name="title">Reset Test Tables</meta>
		<meta name="shortName">testtables_reset</meta>
	</service>

	<fixedQueryCore id="timeoutcore" timeout="1" query=
		"select (select avg(asin(sqrt(x)/224.0)) from generate_series(1, whomp) as x) as q from generate_series(1, 50000) as whomp">
		<outputTable>
			<column name="foo"/>
		</outputTable>
	</fixedQueryCore>

	<service id="timeout" core="timeoutcore">
		<meta name="title">Just wait a while for a timeout</meta>
	</service>

	<service id="limited" core="timeoutcore" limitTo="notYou">
		<meta name="title">Only notYou may see this.</meta>
	</service>

	<service id="dyntemplate" allowed="form,volatile,fixed,qp">
		<meta name="title">Dynamic Template Test</meta>
		<property name="queryField">arg</property>
		<fixedQueryCore query="select table_name from tap_schema.tables limit 1">
			<outputTable>
				<param name="aFloat">1.25</param>
				<column name="table_name" type="text"/>
			</outputTable>
		</fixedQueryCore>
		<template key="fixed">//tpltest.html</template>
		<template key="form">//tpltest.html</template>

		<customDF name="titleList">
				return [
					{"title": "on title", "other": "ing"},
					{"other": "world"}]
		</customDF>

		<customRF name="authinfo">
			if ctx.request.uri.endswith(b"bombout"):
				return open("/dev/null") # nevow can't render a file
			else:
				return ""
		</customRF>
	</service>

	<service id="errors" allowed="form">
		<pythonCore>
			<inputTable>
				<inputKey name="what" type="text"/>
			</inputTable>
			<coreProc>
				<setup>
					<code>
						from gavo import svcs
					</code>
				</setup>
				<code>
					excName = inputTable.getParam("what")
					if excName=="DataError":
						raise base.DataError("test error")
					raise svcs.__dict__[excName]("test error",
						hint="This is for testing")
				</code>
			</coreProc>
		</pythonCore>
	</service>

	<service id="uploads" allowed="form">
		<pythonCore>
			<inputTable>
				<inputKey name="up1" type="file"/>
				<inputKey name="up2" type="file"/>
			</inputTable>
			<coreProc>
				<code>
					up1 = inputTable.getParam("up1")
					up2 = inputTable.getParam("up2")

					return "text/plain", "%s: %s\n%s: %s\n"%(
						up1[0], up1[1].read().decode("utf-8"),
						up2[0], up2[1].read().decode("utf-8"))
				</code>
			</coreProc>
		</pythonCore>
	</service>


	<regSuite id="dachs">
		<regTest title="Auth required for protected form.">
			<url>limited/form</url>
			<code>
				self.assertHTTPStatus(401)
			</code>
		</regTest>

		<regTest title="DB timeout yields a nice response">
			<url>timeout/form</url>
			<code>
				self.assertHasStrings("Just wait a while",
					"Query timed out (took too")
			</code>
		</regTest>

		<regTest title="Admin requires login">
			<url>/seffe/__system__/adql</url>
			<code>
				self.assertHTTPStatus(401)
			</code>
		</regTest>

		<regTest title="Uploads are processed into file items and removed
			from t.w context">
			<url httpMethod="POST" parSet="form">
				<httpUpload fileName="test.txt" name="up1"
					>abc, die Katze lief im Schnee.</httpUpload>
				<httpUpload fileName="a.out" name="up2">hurgl</httpUpload>
				uploads
			</url>
			<code>
				self.assertHasStrings(
					"test.txt: abc, die Katze lief im Schnee.",
					"a.out: hurgl",)
			</code>
		</regTest>

		<regTest title="Chunked uploads work">
			<url httpMethod="POST" parSet="form" httpChunkSize="10">
				<httpUpload fileName="test.txt" name="up1"
					>abc, die Katze lief im Schnee.</httpUpload>
				<httpUpload fileName="a.out" name="up2">hurgl</httpUpload>
				uploads
			</url>
			<code>
				self.assertHasStrings(
					"test.txt: abc, die Katze lief im Schnee.",
					"a.out: hurgl")
			</code>
		</regTest>

		<regTest title="No admin link to bother regular users">
			<url>/__system__/adql/query/form</url>
			<code>
				self.assertLacksStrings("Admin me")
			</code>
		</regTest>

		<regTest title="ADQL docs appear to be in shape">
			<url>/__system__/adql/query/info</url>
			<code><![CDATA[
				self.assertHasStrings("Service Documentation", "About ADQL",
					'">TAP examples</a>')
			]]></code>
		</regTest>

		<regTest title="Vanity redirect works">
			<url>/adql</url>
			<code>
				self.assertHTTPStatus(301)
				self.assertHasStrings('__system__/adql/query/form"',
					"Moved Permanently")
			</code>
		</regTest>

		<regTest title="Table info on non-existing table yields useful error">
			<url>/tableinfo/thistable.doesnotexist</url>
			<code>
				self.assertHasStrings("table 'thistable.doesnotexist' could not be"
					" located in DaCHS' table listing.")
			</code>
		</regTest>

		<regTest title="OAI empty request gives a proper error">
			<url>/oai.xml</url>
			<code><![CDATA[
				self.assertValidatesXSD()
				self.assertHasStrings(
					'<oai:error code="badArgument">verb</oai:error>')
			]]></code>
		</regTest>

		<regTest title="OAI error response validates">
			<url verb="do_a_hiccup">/oai.xml</url>
			<code>
				self.assertValidatesXSD()
				self.assertHasStrings("'do_a_hiccup' is an unsupported operation.")
			</code>
		</regTest>

		<regTest title="OAI Identify validates">
			<url verb="Identify">/oai.xml</url>
			<code>
				self.assertHasStrings("&lt;oai:Identify")
				self.assertValidatesXSD()
			</code>
		</regTest>

		<regTest title="Help page is sanely delivered">
			<url>/static/help.shtml</url>
			<code>
				self.assertHasStrings("Service discovery",
					"Search forms", "VOTable", "sidebar")
			</code>
		</regTest>

		<regTest title="ADQL Parse errors are reported in-form">
			<url parSet="form" query="foobar">/__system__/adql/query/form</url>
			<code>
				self.assertHasStrings("Service info", "Could not parse",
					'Expected SELECT')
			</code>
		</regTest>

		<regTest title="Users table is not accessible through ADQL">
			<url parSet="form" query="select * from dc.users"
				>/__system__/adql/query/form</url>
			<code>
				self.assertHasStrings("Could not locate table", "Result link")
			</code>
		</regTest>

		<regTest title="TAP error message looks like it's according to standard.">
			<url>/__system__/tap/run/sync</url>
			<code><![CDATA[
				self.assertHasStrings('<RESOURCE type="results">',
					'<INFO name="QUERY_STATUS" value="ERROR">',
					"Required parameter 'lang' missing.")
			]]></code>
		</regTest>

		<regTest title="TAP upload with forbidden postgres names works">
			<!-- the stuff that makes this possible is so brittle and ugly
			that I really feel like I need an integration test -->
			<url httpMethod="POST" LANG="ADQL"
				UPLOAD="foo,param:VOT"
				QUERY="SELECT q.*, oid FROM (SELECT oid FROM foo) AS q">
				<httpUpload name="VOT" fileName="tmp.vot"><![CDATA[
					<VOTABLE><RESOURCE><TABLE>
					<FIELD name="oid" datatype="float"/>
					<DATA><TABLEDATA><TR><TD>1</TD></TR></TABLEDATA></DATA>
					</TABLE></RESOURCE></VOTABLE>
				]]></httpUpload>/tap/sync</url>
			<code>
				self.assertXpath("//v:FIELD[1]", {"name": "oid"})
				self.assertXpath("//v:FIELD[2]", {"name": "oid_"})
			</code>
		</regTest>

	</regSuite>

	<regSuite id="cc" title="Caching and compression" sequential="True">
		<regTest title="Root page is well-formed HTML">
			<url>/</url>
			<code>
				from gavo.utils import ElementTree
				tree = ElementTree.fromstring(self.data)
				self.assertEqual(tree[1].tag,
					'{http://www.w3.org/1999/xhtml}body')
			</code>
		</regTest>

		<regTest title="Transparent compression of static resource works">
			<url>
				<value key="Accept-Encoding">gzip</value>/</url>
			<code>
				import gzip, io
				stuff = gzip.GzipFile(fileobj=io.BytesIO(self.data)).read()
				self.assertTrue(b'src="/static/img/logo_medium.png"' in stuff,
				 	"decompressed response looks about right")
				for key, value in self.headers:
					if key=="X-Cache-Creation":
						self.assertFalse(value is None)
						break
				else:
					raise AssertionError("Compressed data comes from Cache")
			</code>
		</regTest>

		<regTest title="Uncompressed root page served from cache">
			<url>/</url>
			<code>
				self.assertHasStrings('src="/static/img/logo_medium.png"')
				for key, value in self.headers:
					if key=="X-Cache-Creation":
						self.assertFalse(value is None)
						break
				else:
					raise AssertionError("No x-cache-creation header")
			</code>
		</regTest>

		<regTest title="Nevow render error yields somewhat usable document">
			<url>dyntemplate/qp/bombout</url>
			<code>
				self.assertHTTPStatus(200) # I'd like this to be a 500, but
					# this error only happens when the status line has been
					# written; HTML streaming is important enough for me with
					# my potentially large HTML tables that I'll suck this up.
					# The 500 will at least be in the log.
				self.assertHasStrings("Internal Error",
					"A(n) FlattenerError exception occurred",
					"UnsupportedType: &amp;lt;_io.TextIOWrapper")
			</code>
		</regTest>
	</regSuite>

	<regSuite title="error documents">
		<LOOP>
			<csvItems>
				excName, expStatus, id, extraText
				UnknownURI,     404, cur-a,   within the data center
				ForbiddenURI,   403, cur-b,   complain fiercely
				WebRedirect,    301, cur-c,   different URL
				SeeOther,       303, cur-d,   Please turn
				Authenticate,   401, cur-e,   access is protected
				BadMethod,      405, cur-f,   HTTP method
				DataError,      406, cur-g,   server cannot generate
				test error,     500, cur-h,   KeyError
			</csvItems>
			<events>
				<regTest title="\excName renders" id="\id">
					<url parSet="form" what="\excName">errors</url>
					<code>
						self.assertHasStrings('href="mailto:')
						self.assertHTTPStatus(\expStatus)
						if "\excName"=="Authenticate":
							# Auth template doesn't show exception
							self.assertHasStrings("\extraText")
						else:
							self.assertHasStrings("test error", "\extraText")
					</code>
				</regTest>
			</events>
		</LOOP>
	</regSuite>

</resource>
