#!/usr/bin/python2.7
# encoding: utf-8
# Copyright 2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test cases for end-to-end testing.  Run with the server_tests script."""

import datetime
import os
import re
import tempfile
from model import *
from server_tests_base import ServerTestsBase


class ImportTests(ServerTestsBase):
    """Tests for CSV import page at /api/import."""
    def setUp(self):
        ServerTestsBase.setUp(self)
        config.set_for_repo(
            'haiti',
            api_action_logging=True)
        self.filename = None

    def tearDown(self):
        if self.filename:
            os.remove(self.filename)
        ServerTestsBase.tearDown(self)

    def _write_csv_file(self, content):
        # TODO(ryok): We should use StringIO instead of a file on disk. Update
        # scrape.py to support StringIO.
        fd, self.filename = tempfile.mkstemp()
        os.fdopen(fd, 'w').write('\n'.join(content))

    def test_import_no_csv(self):
        """Verifies an error message is shown when no CSV file is uploaded."""
        doc = self.go('/haiti/api/import')
        form = doc.cssselect_one('form#persons-import-form')
        doc = self.s.submit(form, key='test_key')
        assert 'Please specify at least one CSV file.' in doc.text

    def test_import_invalid_authentication_key(self):
        """Verifies an error message is shown when auth key is invalid."""
        self._write_csv_file([
            'person_record_id,source_date,full_name',
            'test.google.com/person1,2013-02-26T09:10:00Z,_test_full_name',
            ])
        doc = self.go('/haiti/api/import')
        form = doc.cssselect_one('form#persons-import-form')
        doc = self.s.submit(form, key='bad_key', content=open(self.filename))
        assert 'Missing or invalid authorization key' in doc.text

    def test_import_broken_csv(self):
        """Verifies an error message is shown when a broken CSV is imported."""
        self._write_csv_file([
            'person_record_id,source_date,\0full_name',  # contains null
            'test.google.com/person1,2013-02-26T09:10:00Z,_test_full_name',
            ])
        doc = self.go('/haiti/api/import')
        form = doc.cssselect_one('form#persons-import-form')
        doc = self.s.submit(form, key='test_key', content=open(self.filename))
        assert 'The CSV file is formatted incorrectly' in doc.text
        assert Person.all().count() == 0
        assert Note.all().count() == 0

    def test_import_one_person(self):
        """Verifies a Person entry is successfully imported."""
        self._write_csv_file([
            'person_record_id,source_date,full_name',
            'test.google.com/person1,2013-02-26T09:10:00Z,_test_full_name',
            ])
        doc = self.go('/haiti/api/import')
        form = doc.cssselect_one('form#persons-import-form')
        doc = self.s.submit(form, key='test_key', content=open(self.filename))
        assert 'Person records Imported 1 of 1' in re.sub('\\s+', ' ', doc.text)
        assert Person.all().count() == 1
        assert Note.all().count() == 0
        person = Person.all().get()
        assert person.record_id == 'test.google.com/person1'
        assert person.source_date == datetime.datetime(2013, 2, 26, 9, 10, 0)
        assert person.full_name == '_test_full_name'
        self.verify_api_log(ApiActionLog.WRITE, person_records=1)

    def test_import_one_note(self):
        """Verifies a Note entry is successfully imported."""
        person = Person(
            key_name='haiti:test.google.com/person1',
            repo='haiti',
            author_name='_test_author_name',
            full_name='_test_given_name _test_family_name',
            given_name='_test_given_name',
            family_name='_test_family_name',
            source_date=ServerTestsBase.TEST_DATETIME,
            entry_date=ServerTestsBase.TEST_DATETIME,
            latest_status='',
        )
        db.put(person)

        self._write_csv_file([
            'note_record_id,person_record_id,author_name,source_date,status',
            'test.google.com/note1,test.google.com/person1,' +
            '_test_author_name,2013-02-26T09:10:00Z,believed_alive',
            ])
        doc = self.go('/haiti/api/import')
        form = doc.cssselect_one('form#notes-import-form')
        doc = self.s.submit(form, key='test_key', content=open(self.filename))

        assert 'Note records Imported 1 of 1' in re.sub('\\s+', ' ', doc.text)

        assert Note.all().count() == 1
        note = Note.all().get()
        assert note.record_id == 'test.google.com/note1'
        assert note.person_record_id == 'test.google.com/person1'