/*  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */
package org.apache.aries.transaction.itests;

import static junit.framework.Assert.assertEquals;

import java.sql.SQLException;

import javax.inject.Inject;

import org.apache.aries.transaction.test.TestBean;
import org.junit.Test;
import org.ops4j.pax.exam.util.Filter;

public class NotSupportedTest extends AbstractIntegrationTest {
    @Inject
    @Filter("(tranAttribute=NotSupported)")
    TestBean nsBean;

    @Inject
    @Filter("(tranAttribute=Required)")
    TestBean rBean;

    /**
     * The client transaction is suspended. So the delegate bean that mandates a transaction
     * fails.
     * @throws Exception
     */
    @Test
    public void testNotSupported() throws Exception {
        assertDelegateInsertFails();
        clientTransaction = false;
        assertDelegateInsertFails();
    }

    @Test
    public void testExceptionsDoNotAffectTransaction() throws Exception {
        int initialRows = counter.countRows();

        tran.begin();
        rBean.insertRow("testWithClientTranAndWithRuntimeException", 1, null);
        try {
            nsBean.throwApplicationException();
        } catch (SQLException e) {
            // Ignore expected
        }
        try {
            nsBean.throwRuntimeException();
        } catch (RuntimeException e) {
            // Ignore expected
        }
        tran.commit();

        int finalRows = counter.countRows();
        assertEquals("Added rows", 1, finalRows - initialRows);

    }

    @Override
    protected TestBean getBean() {
        return nsBean;
    }
}
