<commit_before># -*- coding: utf8 -*-
# This file is part of PYBOSSA.
#
# Copyright (C) 2015 Scifabric LTD.
#
# PYBOSSA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PYBOSSA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PYBOSSA.  If not, see <http://www.gnu.org/licenses/>.
# Cache global variables for timeouts

from default import Test, db
from nose.tools import assert_raises
from factories import TaskFactory, TaskRunFactory, ProjectFactory
from pybossa.repositories import TaskRepository, ProjectRepository
from pybossa.exc import WrongObjectError, DBIntegrityError
from pybossa.model.task import Task

project_repo = ProjectRepository(db)


class TestTaskRepositoryForTaskQueries(Test):

    def setUp(self):
        super(TestTaskRepositoryForTaskQueries, self).setUp()
        self.task_repo = TaskRepository(db)


    def test_handle_info_json_plain_text(self):
        """Test handle info in JSON as plain text works."""
        TaskFactory.create(info='answer')
        res = self.task_repo.filter_tasks_by(info='answer')
        assert len(res) == 1
        assert res[0].info == 'answer', res[0]

    def test_handle_info_json(self):
        """Test handle info in JSON works."""
        TaskFactory.create(info={'foo': 'bar'})
        info = 'foo::bar'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]

    def test_handle_info_json_fulltextsearch(self):
        """Test handle info fulltextsearch in JSON works."""
        text = 'bar word agent something'
        TaskFactory.create(info={'foo': text})
        info = 'foo::agent'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1
        assert res[0].info['foo'] == text, res[0]

        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0, len(res)


    def test_handle_info_json_multiple_keys(self):
        """Test handle info in JSON with multiple keys works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|bar::foo'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == 'foo', res[0]

    def test_handle_info_json_multiple_keys_fulltextsearch(self):
        """Test handle info in JSON with multiple keys works."""
        text = "two three four five"
        TaskFactory.create(info={'foo': 'bar', 'extra': text})
        info = 'foo::bar|extra::four'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1, len(res)
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['extra'] == text, res[0]

        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0, len(res)

    def test_handle_info_json_multiple_keys_and_fulltextsearch(self):
        """Test handle info in JSON with multiple keys and AND operator works."""
        text = "agent myself you bar"
        TaskFactory.create(info={'foo': 'bar', 'bar': text})

        info = 'foo::bar|bar::you&agent'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1, len(res)
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == text, res[0]


    def test_handle_info_json_multiple_keys_404(self):
        """Test handle info in JSON with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'daniel': 'foo'})
        info = 'foo::bar|bar::foo'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0

    def test_handle_info_json_multiple_keys_404_with_one_pipe(self):
        """Test handle info in JSON with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == 'foo', res[0]

    def test_handle_info_json_multiple_keys_404_fulltextsearch(self):
        """Test handle info in JSON with full text
        search with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == 'foo', res[0]


    def test_handle_info_json_wrong_data(self):
        """Test handle info in JSON with wrong data works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})

        infos = ['|', '||', '|::', ':|', '::|', '|:', 'foo|', 'foo|']
        for info in infos:
            res = self.task_repo.filter_tasks_by(info=info)
            assert len(res) == 0

        for info in infos:
            res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
            assert len(res) == 0

    def test_get_task_return_none_if_no_task(self):
        """Test get_task method returns None if there is no task with the
        specified id"""

        task = self.task_repo.get_task(200)

        assert task is None, task


    def test_get_task_returns_task(self):
        """Test get_task method returns a task if exists"""

        task = TaskFactory.create()

        retrieved_task = self.task_repo.get_task(task.id)

        assert task == retrieved_task, retrieved_task


    def test_get_task_by(self):
        """Test get_task_by returns a task with the specified attribute"""

        task = TaskFactory.create(state='done')

        retrieved_task = self.task_repo.get_task_by(state=task.state)

        assert task == retrieved_task, retrieved_task


    def test_get_task_by_returns_none_if_no_task(self):
        """Test get_task_by returns None if no task matches the query"""

        TaskFactory.create(state='done')

        task = self.task_repo.get_task_by(state='ongoing')

        assert task is None, task


    def test_filter_tasks_by_no_matches(self):
        """Test filter_tasks_by returns an empty list if no tasks match the query"""

        TaskFactory.create(state='done', n_answers=17)

        retrieved_tasks = self.task_repo.filter_tasks_by(state='ongoing')

        assert isinstance(retrieved_tasks, list)
        assert len(retrieved_tasks) == 0, retrieved_tasks


    def test_filter_tasks_by_one_condition(self):
        """Test filter_tasks_by returns a list of tasks that meet the filtering
        condition"""

        TaskFactory.create_batch(3, state='done')
        should_be_missing = TaskFactory.create(state='ongoing')

        retrieved_tasks = self.task_repo.filter_tasks_by(state='done')

        assert len(retrieved_tasks) == 3, retrieved_tasks
        assert should_be_missing not in retrieved_tasks, retrieved_tasks


    def test_filter_tasks_by_multiple_conditions(self):
        """Test filter_tasks_by supports multiple-condition queries"""

        TaskFactory.create(state='done', n_answers=17)
        task = TaskFactory.create(state='done', n_answers=99)

        retrieved_tasks = self.task_repo.filter_tasks_by(state='done',
                                                         n_answers=99)

        assert len(retrieved_tasks) == 1, retrieved_tasks
        assert task in retrieved_tasks, retrieved_tasks


    def test_filter_tasks_support_yield_option(self):
        """Test that filter_tasks_by with the yielded=True option returns the
        results as a generator"""

        tasks = TaskFactory.create_batch(2, state='done')

        yielded_tasks = self.task_repo.filter_tasks_by(state='done', yielded=True)

        import types
        assert isinstance(yielded_tasks.__iter__(), types.GeneratorType)
        for task in yielded_tasks:
            assert task in tasks


    def test_filter_tasks_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskFactory.create_batch(4)
        all_tasks = self.task_repo.filter_tasks_by()

        first_two = self.task_repo.filter_tasks_by(limit=2)
        last_two = self.task_repo.filter_tasks_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two
        assert len(last_two) == 2, last_two
        assert first_two == all_tasks[:2]
        assert last_two == all_tasks[2:]


    def test_count_tasks_with_no_matches(self):
        """Test count_tasks_with returns 0 if no tasks match the query"""

        TaskFactory.create(state='done', n_answers=17)

        count = self.task_repo.count_tasks_with(state='ongoing')

        assert count == 0, count


    def test_count_tasks_with_one_condition(self):
        """Test count_tasks_with returns the number of tasks that meet the
        filtering condition"""

        TaskFactory.create_batch(3, state='done')
        should_be_missing = TaskFactory.create(state='ongoing')

        count = self.task_repo.count_tasks_with(state='done')

        assert count == 3, count


    def test_count_tasks_with_multiple_conditions(self):
        """Test count_tasks_with supports multiple-condition queries"""

        TaskFactory.create(state='done', n_answers=17)
        task = TaskFactory.create(state='done', n_answers=99)

        count = self.task_repo.count_tasks_with(state='done', n_answers=99)

        assert count == 1, count



class TestTaskRepositoryForTaskrunQueries(Test):

    def setUp(self):
        super(TestTaskRepositoryForTaskrunQueries, self).setUp()
        self.task_repo = TaskRepository(db)


    def test_get_task_run_return_none_if_no_task_run(self):
        """Test get_task_run method returns None if there is no taskrun with the
        specified id"""

        taskrun = self.task_repo.get_task_run(200)

        assert taskrun is None, taskrun


    def test_get_task_run_returns_task_run(self):
        """Test get_task_run method returns a taskrun if exists"""

        taskrun = TaskRunFactory.create()

        retrieved_taskrun = self.task_repo.get_task_run(taskrun.id)

        assert taskrun == retrieved_taskrun, retrieved_taskrun


    def test_get_task_run_by(self):
        """Test get_task_run_by returns a taskrun with the specified attribute"""

        taskrun = TaskRunFactory.create(info='info')

        retrieved_taskrun = self.task_repo.get_task_run_by(info=taskrun.info)

        assert taskrun == retrieved_taskrun, retrieved_taskrun

    def test_get_task_run_by_info_json(self):
        """Test get_task_run_by with JSON returns a
        taskrun with the specified attribute"""

        data = {'foo': 'bar'}
        taskrun = TaskRunFactory.create(info=data)

        info = 'foo::bar'
        retrieved_taskrun = self.task_repo.get_task_run_by(info=info)

        assert taskrun == retrieved_taskrun, retrieved_taskrun

    def test_get_task_run_by_info_json_fulltext(self):
        """Test get_task_run_by with JSON and fulltext returns a
        taskrun with the specified attribute"""

        data = {'foo': 'bar'}
        taskrun = TaskRunFactory.create(info=data)

        info = 'foo::bar'
        retrieved_taskrun = self.task_repo.get_task_run_by(info=info,
                                                           fulltextsearch='1')

        assert taskrun == retrieved_taskrun, retrieved_taskrun



    def test_get_task_run_by_returns_none_if_no_task_run(self):
        """Test get_task_run_by returns None if no taskrun matches the query"""

        TaskRunFactory.create(info='info')

        taskrun = self.task_repo.get_task_run_by(info='other info')

        assert taskrun is None, taskrun


    def test_filter_task_runs_by_no_matches(self):
        """Test filter_task_runs_by returns an empty list if no taskruns match
        the query"""

        TaskRunFactory.create(info='info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='other')

        assert isinstance(retrieved_taskruns, list)
        assert len(retrieved_taskruns) == 0, retrieved_taskruns


    def test_filter_task_runs_by_one_condition(self):
        """Test filter_task_runs_by returns a list of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskFactory.create(info='other info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info')

        assert len(retrieved_taskruns) == 3, retrieved_taskruns
        assert should_be_missing not in retrieved_taskruns, retrieved_taskruns


    def test_filter_task_runs_by_multiple_conditions(self):
        """Test filter_task_runs_by supports multiple-condition queries"""

        TaskRunFactory.create(info='info', user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info='info', user_ip='1.1.1.1')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info',
                                                                user_ip='1.1.1.1')

        assert len(retrieved_taskruns) == 1, retrieved_taskruns
        assert taskrun in retrieved_taskruns, retrieved_taskruns


    def test_filter_task_runs_by_multiple_conditions_fulltext(self):
        """Test filter_task_runs_by supports multiple-condition
        fulltext queries"""

        text = 'you agent something word'
        data = {'foo': 'bar', 'bar': text}
        TaskRunFactory.create(info=data, user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info=data, user_ip='1.1.1.1')

        info = 'foo::bar|bar::agent'
        retrieved_taskruns = self.task_repo.filter_task_runs_by(info=info,
                                                                user_ip='1.1.1.1',
                                                                fulltextsearch='1')

        assert len(retrieved_taskruns) == 1, retrieved_taskruns
        assert taskrun in retrieved_taskruns, retrieved_taskruns

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info=info,
                                                                user_ip='1.1.1.1')
        assert len(retrieved_taskruns) == 0, retrieved_taskruns

    def test_filter_task_runs_support_yield_option(self):
        """Test that filter_task_runs_by with the yielded=True option returns
        the results as a generator"""

        task_runs = TaskRunFactory.create_batch(2, info='info')

        yielded_task_runs = self.task_repo.filter_task_runs_by(info='info',
                                                               yielded=True)

        import types
        assert isinstance(yielded_task_runs.__iter__(), types.GeneratorType)
        for taskrun in yielded_task_runs:
            assert taskrun in task_runs


    def test_filter_tasks_runs_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskRunFactory.create_batch(4)
        all_task_runs = self.task_repo.filter_task_runs_by()

        first_two = self.task_repo.filter_task_runs_by(limit=2)
        last_two = self.task_repo.filter_task_runs_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two<commit_msg>Fix tests as now fulltextsearch returns a tuple<commit_after># -*- coding: utf8 -*-
# This file is part of PYBOSSA.
#
# Copyright (C) 2015 Scifabric LTD.
#
# PYBOSSA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PYBOSSA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PYBOSSA.  If not, see <http://www.gnu.org/licenses/>.
# Cache global variables for timeouts

from default import Test, db
from nose.tools import assert_raises
from factories import TaskFactory, TaskRunFactory, ProjectFactory
from pybossa.repositories import TaskRepository, ProjectRepository
from pybossa.exc import WrongObjectError, DBIntegrityError
from pybossa.model.task import Task

project_repo = ProjectRepository(db)


class TestTaskRepositoryForTaskQueries(Test):

    def setUp(self):
        super(TestTaskRepositoryForTaskQueries, self).setUp()
        self.task_repo = TaskRepository(db)


    def test_handle_info_json_plain_text(self):
        """Test handle info in JSON as plain text works."""
        TaskFactory.create(info='answer')
        res = self.task_repo.filter_tasks_by(info='answer')
        assert len(res) == 1
        assert res[0].info == 'answer', res[0]

    def test_handle_info_json(self):
        """Test handle info in JSON works."""
        TaskFactory.create(info={'foo': 'bar'})
        info = 'foo::bar'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]

    def test_handle_info_json_fulltextsearch(self):
        """Test handle info fulltextsearch in JSON works."""
        text = 'bar word agent something'
        TaskFactory.create(info={'foo': text})
        info = 'foo::agent'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1
        assert res[0][0].info['foo'] == text, res[0]

        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0, len(res)


    def test_handle_info_json_multiple_keys(self):
        """Test handle info in JSON with multiple keys works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|bar::foo'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == 'foo', res[0]

    def test_handle_info_json_multiple_keys_fulltextsearch(self):
        """Test handle info in JSON with multiple keys works."""
        text = "two three four five"
        TaskFactory.create(info={'foo': 'bar', 'extra': text})
        info = 'foo::bar|extra::four'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1, len(res)
        assert res[0][0].info['foo'] == 'bar', res[0]
        assert res[0][0].info['extra'] == text, res[0]

        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0, len(res)

    def test_handle_info_json_multiple_keys_and_fulltextsearch(self):
        """Test handle info in JSON with multiple keys and AND operator works."""
        text = "agent myself you bar"
        TaskFactory.create(info={'foo': 'bar', 'bar': text})

        info = 'foo::bar|bar::you&agent'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1, len(res)
        assert res[0][0].info['foo'] == 'bar', res[0]
        assert res[0][0].info['bar'] == text, res[0]


    def test_handle_info_json_multiple_keys_404(self):
        """Test handle info in JSON with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'daniel': 'foo'})
        info = 'foo::bar|bar::foo'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 0

    def test_handle_info_json_multiple_keys_404_with_one_pipe(self):
        """Test handle info in JSON with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|'
        res = self.task_repo.filter_tasks_by(info=info)
        assert len(res) == 1
        assert res[0].info['foo'] == 'bar', res[0]
        assert res[0].info['bar'] == 'foo', res[0]

    def test_handle_info_json_multiple_keys_404_fulltextsearch(self):
        """Test handle info in JSON with full text
        search with multiple keys not found works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})
        info = 'foo::bar|'
        res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
        assert len(res) == 1
        assert res[0][0].info['foo'] == 'bar', res[0]
        assert res[0][0].info['bar'] == 'foo', res[0]


    def test_handle_info_json_wrong_data(self):
        """Test handle info in JSON with wrong data works."""
        TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'})

        infos = ['|', '||', '|::', ':|', '::|', '|:', 'foo|', 'foo|']
        for info in infos:
            res = self.task_repo.filter_tasks_by(info=info)
            assert len(res) == 0

        for info in infos:
            res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1')
            assert len(res) == 0

    def test_get_task_return_none_if_no_task(self):
        """Test get_task method returns None if there is no task with the
        specified id"""

        task = self.task_repo.get_task(200)

        assert task is None, task


    def test_get_task_returns_task(self):
        """Test get_task method returns a task if exists"""

        task = TaskFactory.create()

        retrieved_task = self.task_repo.get_task(task.id)

        assert task == retrieved_task, retrieved_task


    def test_get_task_by(self):
        """Test get_task_by returns a task with the specified attribute"""

        task = TaskFactory.create(state='done')

        retrieved_task = self.task_repo.get_task_by(state=task.state)

        assert task == retrieved_task, retrieved_task


    def test_get_task_by_returns_none_if_no_task(self):
        """Test get_task_by returns None if no task matches the query"""

        TaskFactory.create(state='done')

        task = self.task_repo.get_task_by(state='ongoing')

        assert task is None, task


    def test_filter_tasks_by_no_matches(self):
        """Test filter_tasks_by returns an empty list if no tasks match the query"""

        TaskFactory.create(state='done', n_answers=17)

        retrieved_tasks = self.task_repo.filter_tasks_by(state='ongoing')

        assert isinstance(retrieved_tasks, list)
        assert len(retrieved_tasks) == 0, retrieved_tasks


    def test_filter_tasks_by_one_condition(self):
        """Test filter_tasks_by returns a list of tasks that meet the filtering
        condition"""

        TaskFactory.create_batch(3, state='done')
        should_be_missing = TaskFactory.create(state='ongoing')

        retrieved_tasks = self.task_repo.filter_tasks_by(state='done')

        assert len(retrieved_tasks) == 3, retrieved_tasks
        assert should_be_missing not in retrieved_tasks, retrieved_tasks


    def test_filter_tasks_by_multiple_conditions(self):
        """Test filter_tasks_by supports multiple-condition queries"""

        TaskFactory.create(state='done', n_answers=17)
        task = TaskFactory.create(state='done', n_answers=99)

        retrieved_tasks = self.task_repo.filter_tasks_by(state='done',
                                                         n_answers=99)

        assert len(retrieved_tasks) == 1, retrieved_tasks
        assert task in retrieved_tasks, retrieved_tasks


    def test_filter_tasks_support_yield_option(self):
        """Test that filter_tasks_by with the yielded=True option returns the
        results as a generator"""

        tasks = TaskFactory.create_batch(2, state='done')

        yielded_tasks = self.task_repo.filter_tasks_by(state='done', yielded=True)

        import types
        assert isinstance(yielded_tasks.__iter__(), types.GeneratorType)
        for task in yielded_tasks:
            assert task in tasks


    def test_filter_tasks_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskFactory.create_batch(4)
        all_tasks = self.task_repo.filter_tasks_by()

        first_two = self.task_repo.filter_tasks_by(limit=2)
        last_two = self.task_repo.filter_tasks_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two
        assert len(last_two) == 2, last_two
        assert first_two == all_tasks[:2]
        assert last_two == all_tasks[2:]


    def test_count_tasks_with_no_matches(self):
        """Test count_tasks_with returns 0 if no tasks match the query"""

        TaskFactory.create(state='done', n_answers=17)

        count = self.task_repo.count_tasks_with(state='ongoing')

        assert count == 0, count


    def test_count_tasks_with_one_condition(self):
        """Test count_tasks_with returns the number of tasks that meet the
        filtering condition"""

        TaskFactory.create_batch(3, state='done')
        should_be_missing = TaskFactory.create(state='ongoing')

        count = self.task_repo.count_tasks_with(state='done')

        assert count == 3, count


    def test_count_tasks_with_multiple_conditions(self):
        """Test count_tasks_with supports multiple-condition queries"""

        TaskFactory.create(state='done', n_answers=17)
        task = TaskFactory.create(state='done', n_answers=99)

        count = self.task_repo.count_tasks_with(state='done', n_answers=99)

        assert count == 1, count



class TestTaskRepositoryForTaskrunQueries(Test):

    def setUp(self):
        super(TestTaskRepositoryForTaskrunQueries, self).setUp()
        self.task_repo = TaskRepository(db)


    def test_get_task_run_return_none_if_no_task_run(self):
        """Test get_task_run method returns None if there is no taskrun with the
        specified id"""

        taskrun = self.task_repo.get_task_run(200)

        assert taskrun is None, taskrun


    def test_get_task_run_returns_task_run(self):
        """Test get_task_run method returns a taskrun if exists"""

        taskrun = TaskRunFactory.create()

        retrieved_taskrun = self.task_repo.get_task_run(taskrun.id)

        assert taskrun == retrieved_taskrun, retrieved_taskrun


    def test_get_task_run_by(self):
        """Test get_task_run_by returns a taskrun with the specified attribute"""

        taskrun = TaskRunFactory.create(info='info')

        retrieved_taskrun = self.task_repo.get_task_run_by(info=taskrun.info)

        assert taskrun == retrieved_taskrun, retrieved_taskrun

    def test_get_task_run_by_info_json(self):
        """Test get_task_run_by with JSON returns a
        taskrun with the specified attribute"""

        data = {'foo': 'bar'}
        taskrun = TaskRunFactory.create(info=data)

        info = 'foo::bar'
        retrieved_taskrun = self.task_repo.get_task_run_by(info=info)

        assert taskrun == retrieved_taskrun, retrieved_taskrun

    def test_get_task_run_by_info_json_fulltext(self):
        """Test get_task_run_by with JSON and fulltext returns a
        taskrun with the specified attribute"""

        data = {'foo': 'bar'}
        taskrun = TaskRunFactory.create(info=data)

        info = 'foo::bar'
        retrieved_taskrun = self.task_repo.get_task_run_by(info=info,
                                                           fulltextsearch='1')

        assert taskrun == retrieved_taskrun, retrieved_taskrun



    def test_get_task_run_by_returns_none_if_no_task_run(self):
        """Test get_task_run_by returns None if no taskrun matches the query"""

        TaskRunFactory.create(info='info')

        taskrun = self.task_repo.get_task_run_by(info='other info')

        assert taskrun is None, taskrun


    def test_filter_task_runs_by_no_matches(self):
        """Test filter_task_runs_by returns an empty list if no taskruns match
        the query"""

        TaskRunFactory.create(info='info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='other')

        assert isinstance(retrieved_taskruns, list)
        assert len(retrieved_taskruns) == 0, retrieved_taskruns


    def test_filter_task_runs_by_one_condition(self):
        """Test filter_task_runs_by returns a list of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskFactory.create(info='other info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info')

        assert len(retrieved_taskruns) == 3, retrieved_taskruns
        assert should_be_missing not in retrieved_taskruns, retrieved_taskruns


    def test_filter_task_runs_by_multiple_conditions(self):
        """Test filter_task_runs_by supports multiple-condition queries"""

        TaskRunFactory.create(info='info', user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info='info', user_ip='1.1.1.1')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info',
                                                                user_ip='1.1.1.1')

        assert len(retrieved_taskruns) == 1, retrieved_taskruns
        assert taskrun in retrieved_taskruns, retrieved_taskruns


    def test_filter_task_runs_by_multiple_conditions_fulltext(self):
        """Test filter_task_runs_by supports multiple-condition
        fulltext queries"""

        text = 'you agent something word'
        data = {'foo': 'bar', 'bar': text}
        TaskRunFactory.create(info=data, user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info=data, user_ip='1.1.1.1')

        info = 'foo::bar|bar::agent'
        retrieved_taskruns = self.task_repo.filter_task_runs_by(info=info,
                                                                user_ip='1.1.1.1',
                                                                fulltextsearch='1')

        assert len(retrieved_taskruns) == 1, retrieved_taskruns
        assert taskrun in retrieved_taskruns[0], retrieved_taskruns

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info=info,
                                                                user_ip='1.1.1.1')
        assert len(retrieved_taskruns) == 0, retrieved_taskruns

    def test_filter_task_runs_support_yield_option(self):
        """Test that filter_task_runs_by with the yielded=True option returns
        the results as a generator"""

        task_runs = TaskRunFactory.create_batch(2, info='info')

        yielded_task_runs = self.task_repo.filter_task_runs_by(info='info',
                                                               yielded=True)

        import types
        assert isinstance(yielded_task_runs.__iter__(), types.GeneratorType)
        for taskrun in yielded_task_runs:
            assert taskrun in task_runs


    def test_filter_tasks_runs_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskRunFactory.create_batch(4)
        all_task_runs = self.task_repo.filter_task_runs_by()

        first_two = self.task_repo.filter_task_runs_by(limit=2)
        last_two = self.task_repo.filter_task_runs_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two
{'fraction_non_alphanumeric': 0.10439490445859873, 'fraction_numerical': 0.009235668789808917, 'mean_word_length': 2.9748101265822786, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 14, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6950869', 'n_tokens_mistral': 9770, 'n_tokens_neox': 9267, 'n_words': 2182}