#!/usr/bin/env python3

import os
import unittest
import server

import flask
from flask import url_for

class VideoTestCase(unittest.TestCase):
	@classmethod
	def tearDownClass(cls):
		os.unlink(server.app.config['SQLITE_DB'])
	
	def setUp(self):
		server.app.testing = True
		self.app = server.app.test_client()

	def login(self, c):
		with c.session_transaction() as sess:
			sess['user'] = {'name': 'videoag', '_csrf_token': 'asd', 'dbid': 72}
			sess['_csrf_token'] = 'asd'

	def test_index(self):
		with self.app as c:
			r = c.get('/')
			assert r.status_code == 200

			self.login(c)
			r = c.get('/')
			assert r.status_code == 200
	
	def test_courses(self):
		with self.app as c:
			r = c.get('/courses')
			assert r.status_code == 200

			self.login(c)
			r = c.get('/courses')
			assert r.status_code == 200

	def test_timetable(self):
		with self.app as c:
			r = c.get('/internal/timetable')
			assert r.status_code == 302

			self.login(c)
			r = c.get('internal/timetable')
			assert r.status_code == 200
			r = c.get('internal/timetable?date=2016-W05')
			assert r.status_code == 200
			assert 'AfI' in r.data.decode()
			assert 'Progra' in r.data.decode()
			assert 'Bio' in r.data.decode()
	
	def test_faq(self):
		r = self.app.get('/faq')
		assert r.status_code == 200

	def test_ical(self):
		with self.app as c:
			r = c.get('/internal/ical/all')
			assert r.status_code == 401

			self.login(c)
			r = c.get('/internal/ical/all')
			assert r.status_code == 200
			assert 'Progra' in r.data.decode()
			assert 'Vorlesung' in r.data.decode()
	
	def test_sitemap(self):
		r = self.app.get('/sitemap.xml')
		assert r.status_code == 200
	
	def test_chapters(self):
		with self.app as c:
			# wrong time format
			r = c.post('/internal/newchapter/7011', data={'text':'testchapter A', 'time': 1234})
			assert r.status_code == 400
			# should be inserted as id 15
			r = c.post('/internal/newchapter/7011', data={'text':'testchapter B', 'time': '00:10:00'})
			assert r.status_code == 200
			# not yet set visible
			r = c.get('/internal/chapters/7011')
			assert r.status_code == 404
			# other lecture
			r = c.get('/internal/chapters/7012')
			assert r.status_code == 404

			self.login(c)
			r = c.post('/internal/edit', data={"chapters.15.visible":1,"_csrf_token":"asd"})
			assert r.status_code == 200
			r = c.get('/internal/chapters/7011')
			assert 'testchapter B' in r.data.decode() and not 'testchapter A' in r.data.decode()

	def test_search(self):
		r = self.app.get('/search?q=Malo')
		assert r.status_code == 200
		assert 'Mathematische Logik II' in r.data.decode() and '4.1 Der Sequenzenkalkül'  in r.data.decode()
		r = self.app.get('/search?q=Afi+Stens')
		assert r.status_code == 200
		assert 'Analysis für Informatiker' in r.data.decode() and 'Höhere Mathematik I'  in r.data.decode()

	def test_login(self):
		# test login page
		r = self.app.get('/internal/login')
		assert r.status_code == 200
		# test successfull login
		with self.app as c:
			r = c.post('/internal/login', data={'user': 'videoag', 'password': 'videoag', 'ref': '/'})
			assert flask.session['user']
			assert r.status_code == 302
			assert '<a href="/">' in r.data.decode()
		# test unsuccessfull login
		with self.app as c:
			r = c.post('/internal/login', data={'user': 'videoag', 'password': 'asd', 'ref': '/'})
			assert flask.session['user']
			assert r.status_code == 403
			assert 'Login fehlgeschlagen' in r.data.decode()

	def test_logout(self):
		with self.app as c:
			with c.session_transaction() as sess:
				sess['user'] = {'foo': 'bar'}
			r = c.get('/internal/logout', data={'ref': '/'})
			assert not flask.session.get('user')
			assert r.status_code == 302
			assert '<a href="/">' in r.data.decode()
	
	def test_edit(self):
		with self.app as c:
			# test auth
			r = c.get('/internal/new/courses', data={'title': 'Neue Vera14352345nstaltung totalyrandomcrap', 'responsible': 'foo', 'handle': '2r5sQ46z4w3DFCRT3<F4>DG', '_csrf_token': 'asd'})
			assert r.status_code != 200

			r = c.get('/internal/changelog')
			assert r.status_code == 302

			# all other tests are done logged in
			self.login(c)

			# add course
			r = c.get('/internal/new/courses', data={'title': 'Neue Veranstaltung totalyrandomcrap', 'responsible': 'foo', 'handle': '2r5sQDFCRT3DG', '_csrf_token': 'asd'})
			assert r.status_code == 200
			r = self.app.get('/courses')
			assert r.status_code == 200
			assert 'Neue Veranstaltung totalyrandomcrap' in r.data.decode() and '2r5sQDFCRT3DG' in r.data.decode()

			# rename lecture
			r = c.get('internal/edit', data={"lectures.7353.title":"Testtitle","_csrf_token":"asd"})
			assert r.status_code == 200

			# test if the changelog is written
			r = c.get('/internal/changelog')
			assert r.status_code == 200
			assert 'Testtitle' in r.data.decode() and 'lectures.7353.title' in r.data.decode()


	def test_legacyurl(self):
		with self.app as c:
			r = self.app.get('/site/feed.php?newcourses')
			assert r.status_code == 302
			assert url_for('courses_feed') in r.data.decode()
			
			r = self.app.get('/?view=faq')
			assert r.status_code == 302
			assert url_for('faq') in r.data.decode()

			r = self.app.get('/site/feed.php?all')
			assert r.status_code == 302
			assert url_for('feed') in r.data.decode()

			r = self.app.get('/?course=16ws-progra')
			assert r.status_code == 302
			assert url_for('course', handle='16ws-progra') in r.data.decode()

			r = self.app.get('/?view=player&lectureid=7319')
			assert r.status_code == 302
			assert url_for('lecture', id='7319', course='16ws-progra') in r.data.decode()

			r = self.app.get('/site/feed.php?16ws-afi')
			assert r.status_code == 302
			assert url_for('feed', handle='16ws-afi') in r.data.decode()

			r = self.app.get('/site/feed.php?lecture=7319')
			assert r.status_code == 302
			assert False # missing

			r = self.app.get('/site/feed.php?vid=6088')
			assert r.status_code == 302
			assert False # missing

if __name__ == '__main__':
	unittest.main()