/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.unitofwork;

import java.util.Vector;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.models.employee.domain.Employee;


/**
 * <p>
 * <b>Purpose</b>: This test checks if TopLink raises exceptions with incorrect operations in UOW
 *
 *     <p>
 * <b>Motivation </b>: This test was written to fix a bug. While in a unit of work, if an object was
 *                                  assigned from the UOW's root session, an exception should be thrown.
 *                                        raised.
 * <p>
 * <b>Design</b>: An employee is read through the session. A unit of work is acquired, an employee
 *                             is read in and assigned to the UOW. The UOW employee sets as its address the address
 *                             of the employee read in from the session. A boolean tracks whether an exception was
 *                             thrown or not. The test passes if an exception was thrown.
 *
 *     <p>
 * <b>Responsibilities</b>: Try to commit an object with a part from an object in the parent session. Verify that
 *                                             an exception is thrown
 * <p>
 *     <b>Features Used</b>: Unit Of Work
 *
 * <p>
 * <b>Paths Covered</b>: Within the unit of work, different parts listed below were set to null:
 *                                <ul>
 *                                <li>    <i>1:1 mapping, QueryException caught</i>, parents sessions address assigned to child session's employee
 *                                </ul>
 *
 *
 *
 * */
public class ExceptionsRaisedUnitOfWorkTest extends AutoVerifyTestCase {

    /**
     * This method was created by a SmartGuide.
     */
    public ExceptionsRaisedUnitOfWorkTest() {
        setDescription("This test verifies that illegal operations will raise exceptions in Unit Of Work.");
    }

    @Override
    protected void setup() {
        getAbstractSession().beginTransaction();
    }

    @Override
    public void reset() {
        getAbstractSession().rollbackTransaction();
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
    }

    @Override
    public void test() { // Read some object from the database.
        boolean exceptionCaught = false;
        Employee employee = (Employee)getSession().readAllObjects(Employee.class).firstElement();

        UnitOfWork firstUOW = getSession().acquireUnitOfWork();

        // Read some object from the database.
        Vector employees = firstUOW.readAllObjects(Employee.class);
        Employee uowEmployee = (Employee)employees.elementAt(2);
        uowEmployee.setAddress(employee.getAddress());

        // commit the unit of work
        try {
            firstUOW.commit();
        } catch (QueryException exception) {
            exceptionCaught = true;
        }
        if (!exceptionCaught) {
            throw new TestErrorException("Performed illegal operations in UOW yet no exception was thrown");
        }
    }
}
