/*! Returns the hash value for \a key. */
uint qHash(const QContactActionDescriptor& key)
{
    uint ret = 0;

    ret += QT_PREPEND_NAMESPACE(qHash)(key.serviceName())
            + QT_PREPEND_NAMESPACE(qHash)(key.actionName())
            + QT_PREPEND_NAMESPACE(qHash)(key.d->m_identifier)
            + QT_PREPEND_NAMESPACE(qHash)(key.implementationVersion())
            + QT_PREPEND_NAMESPACE(qHash)(key.d->m_factory);

    return ret;
}
/*!
  Returns a list of identifiers of the available actions which are provided by the service provider with the given \a serviceName.
  If \a serviceName is empty, actions from all service providers and of any implementation version are returned.
 */
QStringList QContactAction::availableActions(const QString& serviceName)
{
    // SLOW naive implementation...
    QSet<QString> ret;
    QList<QContactActionDescriptor> actionDescriptors = QContactActionManager::instance()->actionDescriptors();
    for (int i = 0; i < actionDescriptors.size(); i++) {
        QContactActionDescriptor descriptor = actionDescriptors.at(i);
        if (serviceName.isEmpty() || serviceName == descriptor.serviceName()) {
            ret.insert(descriptor.actionName());
        }
    }

    return ret.toList();
}
void tst_QContactActions::testDescriptor()
{
    // first, test retrieving an invalid action
    QContactAction* invalidAction = QContactAction::action(QContactActionDescriptor());
    QVERIFY(invalidAction == 0); // should be null.

    QContact c;
    QContactEmailAddress e;
    e.setEmailAddress("*****@*****.**");
    c.saveDetail(&e);
    QContactPhoneNumber p;
    p.setNumber("12345");
    c.saveDetail(&p);

    QVERIFY(QContactAction::availableActions().contains("SendEmail"));
    QVERIFY(QContactAction::availableActions("tst_qcontactactions:sendemailaction").contains("SendEmail"));

    QContactActionDescriptor sendEmailDescriptor;
    QContactActionDescriptor multiActionOneDescriptor;
    QContactActionDescriptor multiActionTwoDescriptor;

    QList<QContactActionDescriptor> descrs = QContactAction::actionDescriptors();
    QContactAction* sendEmailAction = 0;
    for (int i = 0; i < descrs.size(); i++) {
        QContactActionDescriptor temp = descrs.at(i);
        if (temp.actionName() == QString("SendEmail")) {
            sendEmailAction = QContactAction::action(temp);
            QVERIFY(c.availableActions().contains(temp)); // has an email address, so should be available
            QVERIFY(temp.supportsContact(c));
            sendEmailDescriptor = temp;
        } else if (temp.actionName() == QString("call")) {
            if (temp.metaData(QString(QLatin1String("Provider"))) == QString(QLatin1String("sip"))) {
                multiActionOneDescriptor = temp;
            } else {
                multiActionTwoDescriptor = temp;
            }
        }
    }

    QVERIFY(sendEmailDescriptor.isValid());
    QVERIFY(multiActionOneDescriptor.isValid());
    QVERIFY(multiActionTwoDescriptor.isValid());

    QVERIFY(sendEmailAction != 0);
    delete sendEmailAction;

    // now test equivalence.  The send email action descriptor should
    // have a different action name to both multi action one and two.
    QVERIFY(sendEmailDescriptor.actionName() != multiActionOneDescriptor.actionName());
    QVERIFY(sendEmailDescriptor.actionName() != multiActionTwoDescriptor.actionName());
    QVERIFY(sendEmailDescriptor != multiActionOneDescriptor);
    QVERIFY(sendEmailDescriptor != multiActionTwoDescriptor);

    // multi action one and two should have the same action name, service
    // name and implementation (minor) version.  BUT they have different
    // implementations (Provider is different) so they should NOT be equal.
    QVERIFY(multiActionOneDescriptor.actionName() == multiActionTwoDescriptor.actionName());
    QVERIFY(multiActionOneDescriptor.serviceName() == multiActionTwoDescriptor.serviceName());
    QVERIFY(multiActionOneDescriptor.implementationVersion() == multiActionTwoDescriptor.implementationVersion());
    QVERIFY(multiActionOneDescriptor != multiActionTwoDescriptor);

    // verify that the meta data is reported correctly
    QVERIFY(multiActionOneDescriptor.metaData("Provider") != multiActionTwoDescriptor.metaData("Provider"));
}