Example #1
0
    def setUp(self):
        """Manually add a problem to the test database"""
        self.p = Problem(**test_problem)
        self.pd = ProblemData(**test_problem_data)
        self.cases = list()
        for c in test_cases:
            self.cases.append(SampleCase(**c))

        # Ship it off to the db
        try:
            session.add(self.p)
            session.add(self.pd)
            for c in self.cases: session.add(c)
            session.commit()
        except:
            session.rollback()
            _reinsert_test_problem(self.p, self.pd, self.cases)

        # Log in
        self.login()
Example #2
0
def create_problem():
    """Add a new problem to the database and data folder"""
    try:
        # Convert the JSON to python array of dictionaries
        cases = request.form['cases']
        cases = loads(cases)
        for case in cases:
            if 'input' not in case or 'output' not in case:
                return serve_error(
                    'Sample case(s) were not formed correctly',
                    response_code=400)

        # Create the problem
        name = request.form['name'][:32]
        shortname = name.lower().replace(' ', '')
        problem = Problem(
            name=name,
            shortname=shortname
        )
        if 'difficulty' in request.form:
            problem.difficulty = request.form['difficulty']
        if 'appeared_in' in request.form:
            problem.appeared = request.form['appeared_in']
        problem.comp_release = request.form['comp_release'] or None

        # Create the problem data and add it to the database
        problem_data = ProblemData(
            description=request.form['description'],
            input_desc=request.form['input_desc'],
            output_desc=request.form['output_desc']
        )
        if 'time_limit' in request.form:
            problem_data.time_limit = request.form['time_limit']

        # Create list of sample cases
        case_num = 1
        sample_cases = list()
        for case in cases:
            sample = SampleCase(
                case_num=case_num,
                input=case['input'],
                output=case['output']
            )
            case_num += 1
            sample_cases.append(sample)

        in_file = zipfile.ZipFile(request.files['in_file'])
        out_file = zipfile.ZipFile(request.files['out_file'])
        sol_file = request.files['sol_file']

    # If any required values were missing, serve an error
    except KeyError as err:
        return serve_error('Form field not found: ' + err[0],
                           response_code=400)

    # Commit everything to the database
    pid = problem.commit_to_session()
    problem_data.pid = pid
    problem_data.commit_to_session()
    for case in sample_cases:
        case.pid = pid
        case.commit_to_session()

    # Store the judge data
    directory = os.path.join(app.config['DATA_FOLDER'],
                             'problems', str(problem.pid))
    in_file.extractall(directory)
    out_file.extractall(directory)
    os.mkdir(os.path.join(directory, 'test'))
    sol_file.save(os.path.join(directory, 'test', sol_file.filename))

    return serve_response({
        'name': problem.name,
        'shortname': problem.shortname,
        'description': problem_data.description,
        'input_desc': problem_data.input_desc,
        'output_desc': problem_data.output_desc,
        'sample_cases': cases,
        'pid': problem.pid,
        'difficulty': problem.difficulty
    })
Example #3
0
class ProblemGetTests(AUACMTest):
    """Tests functionality for GET-ing problems from the API"""

    def setUp(self):
        """Manually add a problem to the test database"""
        self.p = Problem(**test_problem)
        self.pd = ProblemData(**test_problem_data)
        self.cases = list()
        for c in test_cases:
            self.cases.append(SampleCase(**c))

        # Ship it off to the db
        try:
            session.add(self.p)
            session.add(self.pd)
            for c in self.cases: session.add(c)
            session.commit()
        except:
            session.rollback()
            _reinsert_test_problem(self.p, self.pd, self.cases)

        # Log in
        self.login()

    def tearDown(self):
        """Manually remove test problem from the test database"""
        for c in self.cases:
            session.delete(c)
        session.delete(self.pd)
        session.delete(self.p)
        session.commit()

        # Log out of this session too
        self.logout()

    def testGetAll(self):
        """Should get basic info about all the problems"""
        # Check that the request went through
        resp = test_app.get('/api/problems')
        self.assertEqual(200, resp.status_code)
        rv = json.loads(resp.data.decode())
        self.assertFalse('Please log in' in str(rv))

        # Find the test problem in the list returned
        found = None
        for prob in rv['data']:
            if prob['pid'] == test_problem['pid']:
                found = prob

        self.assertTrue(len(rv['data']) > 0)
        self.assertFalse(found is None)

        # All the original values should be maintained
        for k in test_problem:
            self.assertEqual(str(test_problem[k]), str(found[k]))

    def testGetOne(self):
        """Should get detailed info about one specific problem"""
        resp = test_app.get('/api/problems/' + str(test_problem['pid']))
        self.assertEqual(200, resp.status_code)

        rv = json.loads(resp.data.decode())
        self.assertFalse('Please log in' in str(rv))

        # Time limit doesn't get returned from the API, so take it out of our
        # validation
        data_validate = copy.deepcopy(test_problem_data)
        data_validate.pop('time_limit')

        prob = rv['data']
        for key in test_problem:
            self.assertEqual(str(test_problem[key]), str(prob[key]))
        for key in data_validate:
            self.assertEqual(str(test_problem_data[key]), str(prob[key]))

    def testHideUnreleasedProblem(self):
        """Test that GET-ting an unreleased problem returns a 404"""
        unreleased_cid = self._setUpUnreleasedComp()

        resp = test_app.get('/api/problems/{}'.format(self.p.pid))
        self.assertEqual(404, resp.status_code)

        self._tearDownComp(unreleased_cid)

    def testHideUnreleasedProblems(self):
        """
        Test that GET-ting all problems doesn't return unreleased problems
        """
        unreleased_cid = self._setUpUnreleasedComp()

        resp = test_app.get('/api/problems')
        self.assertEqual(200, resp.status_code)
        rv = json.loads(resp.data.decode())['data']

        # Test problem should be hidden
        for prob in rv:
            self.assertNotEqual(self.p.pid, prob['pid'])

        self._tearDownComp(unreleased_cid)

    def _setUpUnreleasedComp(self):
        """
        Creates an unreleased competition and associates the test's problem with it

        :return: the cid of the new competition
        """
        unreleased_cid = Competition(
            name='Test Competition',
            start=int(time() + 10000),
            stop=int(time() + 20000),
            closed=0
        ).commit_to_session(session)

        self.p.comp_release = unreleased_cid
        self.p.commit_to_session(session)

        return unreleased_cid

    def _tearDownComp(self, cid):
        """Removes a competition from the database by its cid"""
        session.delete(
            session.query(Competition)
            .filter_by(cid=cid)
            .first()
        )
        session.commit()