40 Commits
0.0.8 ... 0.1.3

Author SHA1 Message Date
xevolic
e025b71059 Merge pull request #4 from wiosna-dev/fix/UW-2934_Add_support_for_PHP_8.2
[UW-2934] add support for PHP 8.2
2023-03-09 16:57:33 +01:00
Tomasz Kuter
b658e04445 [UW-2934] chore(composer): updated base version of "wiosna-dev/common-library" 2023-03-09 15:29:22 +01:00
Tomasz Kuter
d4e74bc270 [UW-2934] chore(composer): restored previous repository for wiosna-dev/common-library 2023-02-16 16:39:25 +01:00
Tomasz Kuter
8127330642 [UW-2934] chore(composer): temporarily switched to clone of repo wiosna-dev/common-library 2023-02-15 11:04:55 +01:00
Michał Frankiewicz
f0c213fb53 Merge pull request #3 from wiosna-dev/bugfix/UW-2538
[UW-2538] fixes method
2021-07-02 09:02:33 +02:00
Michał Frankiewicz
24f9a237ae [UW-2538] fixes method 2021-07-02 08:59:44 +02:00
Michał Frankiewicz
81ea8e748f Merge pull request #2 from wiosna-dev/bugfix/UW-2538
Bugfix/uw 2538
2021-06-30 08:36:41 +02:00
Michał Frankiewicz
bab7e25c85 [UW-2538] removes broken argument 2021-06-29 17:11:50 +02:00
Michał Frankiewicz
6423195cc6 [UW-2538] adds method to check survey completion 2021-06-29 17:09:27 +02:00
Michał Frankiewicz
b2d4552fb3 [UW-2538] updates docs 2021-06-29 17:01:03 +02:00
Michał Frankiewicz
53d82841e0 Merge pull request #1 from wiosna-dev/bugfix/UW-2256
Bugfix/uw 2256
2020-07-22 08:40:12 +02:00
Michał Frankiewicz
c8ffcafbd8 [UW-2256] moves token property to BaseParticipant 2020-07-08 08:55:14 +02:00
Michał Frankiewicz
7551f6db95 [UW-2256] adds criteria parameter 2020-07-08 08:54:26 +02:00
Krzysztof Nizioł
a1e681b66e Do not modify version 2018-09-07 21:30:15 +02:00
Krzysztof Nizioł
2c42a2165a Composer > use wiosna-dev/common-library instead of meritoo/common-library package 2018-09-07 21:28:28 +02:00
Krzysztof Nizioł
058eb06d4d Merge branch 'master' of github.com:meritoo/limesurvey-api-client 2018-09-07 13:58:30 +02:00
Meritoo
1389e78068 Phing > tests > missing path of directory with code coverage report 2018-09-07 13:57:19 +02:00
Krzysztof Nizioł
2d3e492ed7 Merge branch 'master' of github.com:meritoo/limesurvey-api-client into develop
# Conflicts:
#	.docker/config/Dockerfile
#	README.md
#	composer.json
2018-09-07 00:01:48 +02:00
Meritoo
2c89bbe5f5 Composer > meritoo/common-library package > use latest version 2018-09-06 23:35:08 +02:00
Meritoo
525391083a Docker > update configuration 2018-09-06 23:33:23 +02:00
Meritoo
7ef83dac5d Phing > update XMLs 2018-09-06 23:32:45 +02:00
Meritoo
54bd021649 Bump version 2018-09-06 23:32:13 +02:00
Meritoo
c47016bdea Readme - configuration of LimeSurvey 2017-11-30 23:41:09 +01:00
Meritoo
c5498501d3 Minor refactoring 2017-11-30 22:54:29 +01:00
Krzysztof Niziol
82031194a2 composer.json - update name of this package (name of vendor, actually) & use exact version constraint of wiosna-dev/common-library package 2017-11-08 15:01:43 +01:00
Krzysztof Niziol
a3e5c78dcd Support PHP 5.5.9+ 2017-11-07 19:09:13 +01:00
Krzysztof Niziol
a3f6adb128 composer.json - missing address of wiosna/common-library package 2017-11-07 18:26:16 +01:00
Krzysztof Niziol
da6003b258 composer.json - update name of this package & use wiosna/common-library (forked from meritoo/common-library) instead of meritoo/common-library package 2017-11-07 15:45:10 +01:00
Meritoo
ee62e9f148 SurveyService - add method that allows to get the "start survey url" using participant's token (instead of whole participant's object) 2017-10-30 19:45:29 +01:00
Meritoo
64e0fb3152 ParticipantService - fix type used in phpdoc 2017-10-26 10:37:20 +02:00
Meritoo
b58c346e95 Tests - use common method to create/prepare date 2017-10-25 20:38:19 +02:00
Meritoo
83ff76776c Fetch all participants of survey (instead of first 10 only - default behaviour) 2017-10-25 20:26:03 +02:00
Meritoo
ac72c6bd76 Do not fetch all participants of given survey to get information if participant has filled the survey 2017-10-25 20:22:48 +02:00
Meritoo
bf7392853f Minor refactoring 2017-10-25 08:38:31 +02:00
Meritoo
e902568a91 Participant & Survey - update creating instance od DateTime from string 2017-10-22 18:20:01 +02:00
Meritoo
626174953b Participant has completed survey - fix getting proper information 2017-10-22 18:18:16 +02:00
Meritoo
ddb568adf7 Tests - Docker - update Xdebug configuration
Required to fix problem "Connection with XDebug 2.5.1 was not established. Validate installation."
2017-10-22 17:56:24 +02:00
Meritoo
835c4325b8 Tests - missing description of method 2017-10-19 21:57:35 +02:00
Meritoo
24a3d478b5 Tests - use Docker (as environment guard) 2017-10-19 21:44:25 +02:00
Meritoo
e38df1a8f2 Start names of special directories with dot 2017-10-18 21:21:53 +02:00
57 changed files with 2422 additions and 972 deletions

15
.env Normal file
View File

@@ -0,0 +1,15 @@
# -----------------------------------------------------------------------------
### Docker
# -----------------------------------------------------------------------------
#
# All containers
#
DOCKER_CONTAINER_OWNER=meritoo
DOCKER_CONTAINER_PROJECT=limesurvey-api-client
#
# PHP configuration:
# - timezone
#
TIMEZONE=Europe/Warsaw

8
.gitignore vendored
View File

@@ -29,10 +29,16 @@
# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
/.php_cs.cache /.php_cs.cache
# ----------------------------------------------------------------------------------------------------------------------
### Build files
# ----------------------------------------------------------------------------------------------------------------------
/.build/
# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
### Generated databases ### Generated databases
# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
/data/tmp /.data/tmp
*.sql *.sql
*.sqlite *.sqlite

View File

@@ -5,14 +5,38 @@ Client of the [LimeSurvey's API](https://manual.limesurvey.org/RemoteControl_2_A
## Installation ## Installation
In your `composer.json` add address of repository into `repositories` section:
```json
"repositories": [
(...)
{
"type": "vcs",
"url": "https://github.com/wiosna-dev/limesurvey-api-client"
}
]
```
Run [Composer](https://getcomposer.org) to install this package in your project: Run [Composer](https://getcomposer.org) to install this package in your project:
```bash ```bash
$ composer require meritoo/limesurvey-api-client $ composer require wiosna-dev/limesurvey-api-client
``` ```
> How to install Composer: https://getcomposer.org/download > How to install Composer: https://getcomposer.org/download
## Configuration of LimeSurvey
1. Login to the LimeSurvey administration, e.g. using https://your-domain/admin address
2. Go to menu: `Configuration` -> `Global settings`
3. Open `Interfaces` tab
4. For `RPC interface enabled` select `JSON-RPC` option
5. Enable `Publish API on /admin/remotecontrol` option
It should look like here:
![Configuration of LimeSurvey](http://www.meritoo.pl/packages/github/limesurvey-api-client/readme/configuration-interfaces.png)
More information: https://manual.limesurvey.org/RemoteControl_2_API#Introduction
## Usage ## Usage
1. First of all you have to prepare configuration of connection and create instance of a client: 1. First of all you have to prepare configuration of connection and create instance of a client:

1
VERSION Normal file
View File

@@ -0,0 +1 @@
0.1.1

View File

@@ -4,32 +4,32 @@
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties" /> <property file="phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist" /> <property file="phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:app, build:tests" depends="build:app, build:tests"
description="Builds everything and runs all tests" /> description="Builds everything and runs all tests"/>
<!-- Build app --> <!-- Build app -->
<target name="build:app" description="Prepares app to build and tests"> <target name="build:app" description="Prepares app to build and tests">
<phing phingfile="phing/app.xml" haltonfailure="true" /> <phing phingfile="phing/app.xml" haltonfailure="true"/>
</target> </target>
<!-- Build tests --> <!-- Build tests -->
<target name="build:tests" description="Runs all tests, checks and creates docs"> <target name="build:tests" description="Runs all tests, checks and creates docs">
<phing phingfile="phing/tests.xml" haltonfailure="true" /> <phing phingfile="phing/tests.xml" haltonfailure="true"/>
<!-- <!--
Conditional running of tests. Conditional running of tests.
Disabled, because not required. Disabled, because not required.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<if> <if>

View File

@@ -1,9 +1,8 @@
{ {
"name": "meritoo/limesurvey-api-client", "name": "wiosna-dev/limesurvey-api-client",
"description": "Client of LimeSurvey API", "description": "Client of LimeSurvey API",
"type": "library", "type": "library",
"license": "MIT", "license": "MIT",
"version": "0.0.8",
"authors": [ "authors": [
{ {
"name": "Meritoo", "name": "Meritoo",
@@ -11,17 +10,18 @@
} }
], ],
"require": { "require": {
"php": ">=5.6",
"fguillot/json-rpc": "^1.2", "fguillot/json-rpc": "^1.2",
"meritoo/common-library": "~0.0.1" "wiosna-dev/common-library": "^0.1.9"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^5.7", "friendsofphp/php-cs-fixer": "^2.6",
"squizlabs/php_codesniffer": "^2.9",
"phpmd/phpmd": "^2.6",
"sebastian/phpcpd": "^3.0",
"pdepend/pdepend": "^2.5", "pdepend/pdepend": "^2.5",
"phploc/phploc": "^4.0", "phploc/phploc": "^4.0",
"friendsofphp/php-cs-fixer": "^2.6" "phpmd/phpmd": "^2.6",
"phpunit/phpunit": "^5.7",
"sebastian/phpcpd": "^3.0",
"squizlabs/php_codesniffer": "^2.9"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -32,5 +32,14 @@
"psr-4": { "psr-4": {
"Meritoo\\LimeSurvey\\Test\\ApiClient\\": "tests/" "Meritoo\\LimeSurvey\\Test\\ApiClient\\": "tests/"
} }
} },
"config": {
"sort-packages": true
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/wiosna-dev/common-library"
}
]
} }

20
docker-compose.yml Normal file
View File

@@ -0,0 +1,20 @@
version: '3'
services:
php:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
entrypoint: php
command: -S 0.0.0.0:9999
build:
context: ./docker/config
args:
- TIMEZONE=${TIMEZONE}
volumes:
- .:/project:cached
composer:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
entrypoint: composer
volumes:
- .:/project:cached

103
docker/config/Dockerfile Normal file
View File

@@ -0,0 +1,103 @@
FROM php:5.6-cli
MAINTAINER Meritoo <github@meritoo.pl>
#
# Tools & libraries
#
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
vim \
git \
zip \
unzip \
zlib1g-dev \
libicu-dev \
&& apt-get clean \
&& rm -rf \
/var/lib/apt/lists/* \
/tmp/* \
/var/tmp/*
#
# PHP extensions
#
RUN docker-php-ext-install \
zip \
intl \
mbstring
#
# PHP extensions (PECL):
# - Xdebug
#
RUN pecl install \
xdebug-2.5.5 \
&& docker-php-ext-enable \
xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#
# PHP configuration:
# - default configuration
# - timezone
#
COPY php.ini /usr/local/etc/php/php.ini
ARG TIMEZONE
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo ${TIMEZONE} > /etc/timezone \
&& printf '[PHP]\ndate.timezone = "%s"\n' ${TIMEZONE} > /usr/local/etc/php/conf.d/tzone.ini \
&& "date"
#
# Phing
#
RUN pear channel-discover pear.phing.info \
&& pear install [--alldeps] phing/phing
#
# Composer - environment variables:
# - disable warning about running commands as root/super user
# - disable automatic clearing of sudo sessions
#
# More:
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
#
ENV COMPOSER_ALLOW_SUPERUSER 1
#
# Composer + https://packagist.org/packages/hirak/prestissimo package
#
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === \
'544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo \
'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');" \
&& composer global require \
--no-plugins \
--no-scripts \
--no-progress \
--no-suggest \
--no-interaction \
--prefer-dist \
--optimize-autoloader \
--classmap-authoritative \
hirak/prestissimo \
&& rm -rf ~/.composer/cache/* \
&& composer clear-cache \
&& composer --version
#
# Bash
#
RUN sed -i 's/^# export/export/g; \
s/^# alias/alias/g;' ~/.bashrc \
&& echo 'COLUMNS=200'"\n" >> ~/.bashrc
#
# Use project-related binaries globally
#
ENV PATH="/project/vendor/bin:${PATH}"
WORKDIR /project

3
docker/config/php.ini Normal file
View File

@@ -0,0 +1,3 @@
display_errors = On
display_startup_errors = On
error_reporting = E_ALL

6
docker/config/xdebug.ini Normal file
View File

@@ -0,0 +1,6 @@
[xdebug]
zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_port=9001
xdebug.remote_host=10.254.254.254

View File

@@ -1,53 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0"> <project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties" /> <property file="phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist" /> <property file="phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Filesets -->
<import file="phing/filesets.xml"/>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:app" depends="build:app"
description="Builds the application" /> description="Builds the application"/>
<!-- App target --> <!-- App target -->
<target name="build:app" <target name="build:app"
depends="app:composer, app:vendors, app:checkout" depends="app:clean, app:composer, app:vendors, app:composer-validate, app:checkout"
description="Prepares app to build." /> description="Prepares app to build."/>
<!-- Check / update composer --> <!-- Updates Composer -->
<target name="app:composer" description="Checks / updates composer"> <target name="app:composer" description="Updates Composer">
<echo msg="Checking / updating composer..." /> <echo msg="Updating Composer..."/>
<if> <if>
<available file="composer.phar" /> <available file="composer.phar"/>
<then> <then>
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." /> <echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..."/>
</then> </then>
<else> <else>
<if> <if>
<os family="windows" /> <os family="windows"/>
<then> <then>
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." /> <fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer."/>
</then> </then>
<else> <else>
<exec command="${composer.download_command}" checkreturn="true" /> <exec command="${composer.download_command}" checkreturn="true"/>
</else> </else>
</if> </if>
</else> </else>
</if> </if>
<composer command="selfupdate" />
<!-- Update Composer -->
<composer command="selfupdate"/>
</target>
<!-- Validates composer.* files -->
<target name="app:composer-validate" description="Validates composer.* files">
<echo msg="Validating composer.* files..."/>
<!-- Validate Composer -->
<composer command="validate">
<arg line="--no-check-all --strict"/>
</composer>
</target>
<!-- Project clean -->
<target name="app:clean" description="Clears app's directories">
<echo msg="Cleaning project..."/>
<if>
<equals arg1="${env}" arg2="prod"/>
<then>
<echo message="[Skipped] Cleaning project (and directories cleanup) skipped, because of 'prod' environment..."/>
</then>
<else>
<echo msg="Cleaning directories (making them empty)..."/>
<foreach list="${directoriesToEmpty}" param="directory" target="app:clean:empty"/>
</else>
</if>
<echo msg="Preparing directories structure..."/>
<foreach list="${directoriesToCheck}" param="directory" target="app:clean:check"/>
<echo msg="Creating .gitkeep files..."/>
<touch file="${dir.cache}/.gitkeep"/>
<touch file="${dir.logs}/.gitkeep"/>
<touch file="${dir.sessions}/.gitkeep"/>
<echo msg="Setting permissions of directories..."/>
<foreach list="${directoriesToEmpty}" param="directory" target="app:permissions"/>
</target>
<!-- Cleaning directory (making empty) directory -->
<target name="app:clean:empty" description="Empties directory">
<if>
<available file="${directory}" type="dir"/>
<then>
<echo message="Cleaning directory (making empty) ${directory}..."/>
<delete includeemptydirs="true" dir="${directory}"/>
</then>
</if>
</target>
<!-- Checking if directory exists -->
<target name="app:clean:check" description="Checks if directories exist">
<if>
<not>
<available file="${directory}" type="dir"/>
</not>
<then>
<if>
<or>
<contains string="${directory}" substring="cache"/>
<contains string="${directory}" substring="logs"/>
<contains string="${directory}" substring="sessions"/>
</or>
<then>
<mkdir dir="${directory}" mode="0777"/>
</then>
<else>
<mkdir dir="${directory}" mode="0775"/>
</else>
</if>
</then>
</if>
</target> </target>
<!-- Project Install/update vendors --> <!-- Project Install/update vendors -->
<target name="app:vendors" description="Installs / updates vendors"> <target name="app:vendors" description="Installs / updates vendors">
<echo msg="Installing / updating vendors..." /> <echo msg="Installing / updating vendors..."/>
<if> <if>
<istrue value="${composer.self-update}"/> <istrue value="${composer.self-update}"/>
@@ -56,34 +132,33 @@
</then> </then>
</if> </if>
<if> <composer php="${composer.php}" composer="${composer.path}" command="install">
<istrue value="${composer.validate}"/> <arg value="--optimize-autoloader"/>
<then> <arg value="--prefer-dist"/>
<composer php="${composer.php}" composer="${composer.path}" command="validate"/> <arg value="--classmap-authoritative"/>
</then> </composer>
</if> </target>
<!-- Setting permissions of given directory -->
<target name="app:permissions" description="Sets permissions of one of the core directories">
<if> <if>
<equals arg1="${env}" arg2="prod" /> <not>
<os family="windows"/>
</not>
<then> <then>
<composer php="${composer.php}" composer="${composer.path}" command="install"> <exec command="chmod -R 777 ${directory}/*"/>
<arg value="--optimize-autoloader" />
</composer>
</then> </then>
<else>
<composer php="${composer.php}" composer="${composer.path}" command="install" />
</else>
</if> </if>
</target> </target>
<!-- Checkout and finalization --> <!-- Checkout and finalization -->
<target name="app:checkout"> <target name="app:checkout">
<tstamp> <tstamp>
<format property="date_end" pattern="%Y-%m-%d %H:%M" /> <format property="date_end" pattern="%Y-%m-%d %H:%M"/>
</tstamp> </tstamp>
<echo msg="------------------------------------" /> <echo msg="------------------------------------"/>
<echo msg="Build finished at: ${date_end}" /> <echo msg="Build finished at: ${date_end}"/>
<echo msg="------------------------------------" /> <echo msg="------------------------------------"/>
</target> </target>
</project> </project>

35
phing/filesets.xml Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Filesets -->
<fileset id="cache" dir="${dir.cache}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<fileset id="logs" dir="${dir.logs}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<fileset id="sessions" dir="${dir.sessions}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<!-- Directories to check -->
<property name="directoriesToCheck" value="
${dir.cache},
${dir.logs},
${dir.sessions},
${dir.data.tests},
${dir.data.temporary},
${dir.docker.data},
${dir.docker.logs}"
/>
<!-- Directories to empty -->
<property name="directoriesToEmpty" value="
${dir.cache},
${dir.logs},
${dir.sessions},
${dir.data.temporary}"
/>
</project>

View File

@@ -9,7 +9,7 @@
# not special chars. This way you can create pseudo-namespaces # not special chars. This way you can create pseudo-namespaces
# #
# You can refer to values of other properties by enclosing their keys in "${}". # You can refer to values of other properties by enclosing their keys in "${}".
# Example: dir.js = ${dir.web}/js # Example: dir.js = ${dir.public}/js
# #
# Everything behind the equal sign is the value, you do # Everything behind the equal sign is the value, you do
# not have to enclose strings: text=This is some text, Your OS is ${php.os} # not have to enclose strings: text=This is some text, Your OS is ${php.os}
@@ -22,13 +22,15 @@
# #
env = dev env = dev
# Install assets using symlinks
#
assets.installWithSymlink = true
# Clear cache with the "warmup" option # Clear cache with the "warmup" option
# #
cache.clearWithWarmup = true # The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command.
# https://github.com/symfony/symfony/blob/master/UPGRADE-3.3.md#frameworkbundle
#
# Meritoo <github@meritoo.pl>
# 2017-06-06
#
cache.clearWithWarmup = false
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Composer # Composer
@@ -39,7 +41,6 @@ composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomp
# Path to composer executable or composer.phar file # Path to composer executable or composer.phar file
# #
composer.path = composer.phar composer.path = composer.phar
#composer.path = /usr/local/bin/composer
# Path to php executable used by composer # Path to php executable used by composer
# #
@@ -49,77 +50,50 @@ composer.php = php
# #
composer.self-update = false composer.self-update = false
# Validate the composer.json file
#
composer.validate = false
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Directories # Directories
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# System directories # System directories
# #
dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src dir.src = ${project.basedir}/src
dir.var = ${project.basedir}/tests/Resources/var
dir.cache = ${dir.var}/cache
dir.logs = ${dir.var}/log
dir.sessions = ${dir.var}/sessions
dir.data = ${project.basedir}/data
dir.tests = ${project.basedir}/tests dir.tests = ${project.basedir}/tests
# --------------------------------------------------------------------------------
# Build directories # Build directories
# -------------------------------------------------------------------------------- #
dir.build = ${project.basedir}/build dir.build = ${project.basedir}/build
dir.reports = ${dir.build}/logs dir.reports = ${dir.build}/logs
dir.reports.pdepend = ${dir.reports}/pdepend dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage dir.reports.coverage = ${dir.reports}/phpunit_coverage
#
# Disabled, because unnecessary right now
# phpdocumentor/phpdocumentor cannot be installed via Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
#dir.docs = ${dir.build}/docs
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
# --------------------------------------------------------------------------------
# Data directories # Data directories
# -------------------------------------------------------------------------------- #
dir.data.tests = ${dir.data}/tests dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp dir.data.temporary = ${dir.data}/tmp
# Docker directories
#
dir.docker = ${project.basedir}/docker
dir.docker.data = ${dir.docker}/data/db
dir.docker.logs = ${dir.docker}/logs/nginx
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Testing # Testing
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
tests.cs_fixer.path = ./vendor/bin/php-cs-fixer
# Test database path # Test database path
# #
tests.database = ${dir.data.temporary}/database.sqlite tests.database = ${dir.data.temporary}/database.sqlite
# Path of the framework used to run unit tests
# #
# Disabled, because unnecessary right now tests.framework.path = ./vendor/bin/phpunit --verbose --no-coverage
# PHPUnit is installed and loaded by Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Run PHPUnit using exec task instead of phpunitTask
#phpunit.useExec = false
#
# Disabled, because unnecessary right now
# We want generate code coverage always
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Collect coverage data during tests
#phpunit.withCoverage = true
# Path of the PHPUnit (https://phpunit.de)
#
phpUnit.path = ./vendor/bin/phpunit
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
phpCsFixer.path = ./vendor/bin/php-cs-fixer

View File

@@ -4,39 +4,39 @@
The AutoloaderTask is required to load binaries installed by Composer. The AutoloaderTask is required to load binaries installed by Composer.
The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php. The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-23 2017-02-23
--> -->
<autoloader /> <autoloader/>
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties" /> <property file="phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist" /> <property file="phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Filesets --> <!-- Filesets -->
<fileset id="sourcecode" dir="${dir.src}"> <fileset id="sourcecode" dir="${dir.src}">
<include name="**/*.php" /> <include name="**/*.php"/>
<exclude name="*Test.php" /> <exclude name="*Test.php"/>
<exclude name="**/*Test.php" /> <exclude name="**/*Test.php"/>
<exclude name="**/Resources/**" /> <exclude name="**/Resources/**"/>
<exclude name="**/DataFixtures/**" /> <exclude name="**/DataFixtures/**"/>
<exclude name="**/Tests/**" /> <exclude name="**/Tests/**"/>
</fileset> </fileset>
<fileset id="tests" dir="${dir.tests}"> <fileset id="tests" dir="${dir.tests}">
<include name="**/*Test*.php" /> <include name="**/*Test*.php"/>
</fileset> </fileset>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout" depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
description="Runs all tests and builds everything" /> description="Runs all tests and builds everything"/>
<!-- <!--
Before: Before:
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout" depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout"
@@ -48,13 +48,13 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) --> <!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
<target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer"> <target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer">
<echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..." /> <echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..."/>
<!-- <!--
Attention. Attention.
@@ -62,8 +62,8 @@
--> -->
<exec <exec
passthru="true" passthru="true"
command="${phpCsFixer.path} fix --verbose" command="${tests.cs_fixer.path} fix --verbose"
/> />
</target> </target>
@@ -73,38 +73,38 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
<!--<target name="build:doc"--> <!--<target name="build:doc"-->
<!--depends="build:prepare, doc:phpdoc2"--> <!--depends="build:prepare, doc:phpdoc2"-->
<!--description="Generates API documentation" />--> <!--description="Generates API documentation" />-->
<!-- Check target --> <!-- Check target -->
<target name="build:check" <target name="build:check"
depends="check:cs, check:md, check:cpd, check:depend, check:loc" depends="check:cs, check:md, check:cpd, check:depend, check:loc"
description="Analyzes code" /> description="Analyzes code"/>
<!-- Test target --> <!-- Test target -->
<target name="build:test" <target name="build:test"
depends="test:phpunit" depends="test:unit"
description="Executes all tests" /> description="Executes all tests"/>
<!-- Project build clean --> <!-- Project build clean -->
<target name="build:clean" description="Cleans up build directories"> <target name="build:clean" description="Cleans up build directories">
<echo msg="Cleaning docs and reports directories..." /> <echo msg="Cleaning docs and reports directories..."/>
<!--<delete dir="${dir.docs}" />--> <!--<delete dir="${dir.docs}" />-->
<delete dir="${dir.reports}" /> <delete dir="${dir.reports}"/>
</target> </target>
<!-- Project build prepare --> <!-- Project build prepare -->
<target name="build:prepare" description="Create build directories"> <target name="build:prepare" description="Create build directories">
<echo msg="Creating build directories..." /> <echo msg="Creating build directories..."/>
<!--<mkdir dir="${dir.docs}" />--> <!--<mkdir dir="${dir.docs}" />-->
<!--<mkdir dir="${dir.docs.phpdoc2}" />--> <!--<mkdir dir="${dir.docs.phpdoc2}" />-->
<mkdir dir="${dir.reports}" /> <mkdir dir="${dir.reports}"/>
<mkdir dir="${dir.reports.coverage}" /> <mkdir dir="${dir.reports.pdepend}"/>
<mkdir dir="${dir.reports.pdepend}" /> <mkdir dir="${dir.reports.coverage}"/>
</target> </target>
<!-- PHPDocumentor2 API documentation target --> <!-- PHPDocumentor2 API documentation target -->
@@ -113,7 +113,7 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<target name="doc:phpdoc2" description="Generates API documentations"> <target name="doc:phpdoc2" description="Generates API documentations">
@@ -142,31 +142,31 @@
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding
Standards Fixer (http://cs.sensiolabs.org) is used. Standards Fixer (http://cs.sensiolabs.org) is used.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
<target name="check:cs" description="Checks coding standard"> <target name="check:cs" description="Checks coding standard">
<echo msg="Checking coding standard..." /> <echo msg="Checking coding standard..."/>
<phpcodesniffer standard="PSR2" showWarnings="true"> <phpcodesniffer standard="PSR2" showWarnings="true">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" /> <formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml"/>
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" /> <formatter type="csv" outfile="${dir.reports}/checkstyle.csv"/>
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" /> <formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt"/>
</phpcodesniffer> </phpcodesniffer>
</target> </target>
<!-- copy/paste detector --> <!-- copy/paste detector -->
<target name="check:cpd" description="Checks similar code blocks."> <target name="check:cpd" description="Checks similar code blocks.">
<echo msg="Checking similar code blocks..." /> <echo msg="Checking similar code blocks..."/>
<phpcpd> <phpcpd>
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml" /> <formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml"/>
</phpcpd> </phpcpd>
<!-- <!--
Previous / old version Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" /> <exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
@@ -175,36 +175,36 @@
<!-- Mess detector --> <!-- Mess detector -->
<target name="check:md" description="Generate code metrics"> <target name="check:md" description="Generate code metrics">
<echo msg="Generating code metrics..." /> <echo msg="Generating code metrics..."/>
<phpmd rulesets="codesize,controversial,design,naming,unusedcode"> <phpmd rulesets="codesize,controversial,design,naming,unusedcode">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="html" outfile="${dir.reports}/phpmd.html" /> <formatter type="html" outfile="${dir.reports}/phpmd.html"/>
<formatter type="text" outfile="${dir.reports}/phpmd.txt" /> <formatter type="text" outfile="${dir.reports}/phpmd.txt"/>
</phpmd> </phpmd>
</target> </target>
<!-- Code dependency --> <!-- Code dependency -->
<target name="check:depend" description="Checks coupling and dependency"> <target name="check:depend" description="Checks coupling and dependency">
<echo msg="Checking coupling and dependency..." /> <echo msg="Checking coupling and dependency..."/>
<phpdepend> <phpdepend>
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml" /> <logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml"/>
<logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg" /> <logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg"/>
<logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg" /> <logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg"/>
</phpdepend> </phpdepend>
</target> </target>
<!-- Measure the size and analyzing the structure of a project --> <!-- Measure the size and analyzing the structure of a project -->
<target name="check:loc" description="Measures the size and analyzes the structure of a project"> <target name="check:loc" description="Measures the size and analyzes the structure of a project">
<echo msg="Measuring the size and analyzing the structure of a project..." /> <echo msg="Measuring the size and analyzing the structure of a project..."/>
<phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}"> <phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
</phploc> </phploc>
<!-- <!--
Previous / old version Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" /> <exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
@@ -212,104 +212,19 @@
</target> </target>
<!-- Unit tests --> <!-- Unit tests -->
<target name="test:phpunit" description="Executes PHPUnit tests"> <target name="test:unit" description="Runs unit tests">
<!-- Check test database --> <echo msg="Running unit tests..."/>
<if> <exec command="${tests.framework.path}" passthru="true"/>
<not>
<available file="${dir.data.tests}" type="dir" property="dir.data.tests.available" />
</not>
<then>
<mkdir dir="${dir.data.tests}" />
</then>
</if>
<if>
<not>
<available file="${tests.database}" property="tests.database.available" />
</not>
<then>
<touch file="${tests.database}" />
</then>
</if>
<echo msg="Running unit tests..." />
<coverage-setup database="${dir.reports.coverage}/coverage.db">
<fileset refid="sourcecode" />
</coverage-setup>
<exec command="${phpUnit.path} --verbose --configuration ${project.basedir}/phpunit.xml.dist" passthru="true" />
<!--
I have to use ExecTask to run PHPUnit instead of PHPUnitTask, because tests are not running if PHPUnitTask is
used (don't know why):
Total tests run: 0, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-23
<phpunit configuration="${project.basedir}/phpunit.xml.dist" printsummary="true">
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
<formatter type="clover" todir="${dir.reports.coverage}" />
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
</phpunit>
-->
<!--
Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<if>
<istrue value="${phpunit.useExec}" />
<then>
<if>
<istrue value="${phpunit.withCoverage}" />
<then>
<echo message="Running tests with code coverage..." />
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml \-\-coverage-clover ${dir.reports.coverage}/clover-coverage.xml \-\-coverage-crap4j ${dir.reports.coverage}/crap4j-coverage.xml \-\-coverage-html ${dir.reports.coverage}/ -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
</then>
<else>
<echo message="Running tests without code coverage..." />
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
</else>
</if>
</then>
<else>
<if>
<istrue value="${phpunit.withCoverage}" />
<then>
<echo message="Running tests with code coverage..." />
<coverage-setup database="${dir.reports.coverage}/coverage.db">
<fileset refid="sourcecode" />
</coverage-setup>
<phpunit printsummary="true" codecoverage="true">
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
<formatter type="clover" todir="${dir.reports.coverage}" />
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
</phpunit>
</then>
<else>
<echo message="Running tests without code coverage..." />
<phpunit printsummary="true">
<formatter todir="${dir.reports}" type="xml" outfile="phpunit.xml" />
<batchtest>
<fileset refid="tests" />
</batchtest>
</phpunit>
</else>
</if>
</else>
</if>
-->
</target> </target>
<!-- Checkout and finalization --> <!-- Checkout and finalization -->
<target name="app:checkout"> <target name="app:checkout">
<tstamp> <tstamp>
<format property="date_end" pattern="%Y-%m-%d %H:%M" /> <format property="date_end" pattern="%Y-%m-%d %H:%M"/>
</tstamp> </tstamp>
<echo msg="--------------------------------------------" /> <echo msg="--------------------------------------------"/>
<echo msg="Build tests finished at: ${date_end}" /> <echo msg="Build tests finished at: ${date_end}"/>
<echo msg="--------------------------------------------" /> <echo msg="--------------------------------------------"/>
</target> </target>
</project> </project>

View File

@@ -30,6 +30,6 @@
</groups> </groups>
<logging> <logging>
<log type="coverage-html" target="./build/logs/phpunit_coverage/html" /> <log type="coverage-html" target="./.build/logs/phpunit_coverage/html" />
</logging> </logging>
</phpunit> </phpunit>

View File

@@ -0,0 +1,98 @@
<?php
namespace Meritoo\LimeSurvey\ApiClient\Base\Result;
/**
* Base class for participant of survey.
* Used as a foundation for short or full participant's data.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseParticipant extends BaseItem
{
/**
* ID of the participant
*
* @var int
*/
protected $id;
/**
* First name of the participant
*
* @var string
*/
protected $firstName;
/**
* Last name of the participant
*
* @var string
*/
protected $lastName;
/**
* E-mail of the participant
*
* @var string
*/
protected $email;
/**
* Token of the participant
*
* @var string
*/
protected $token;
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Returns token of the participant
*
* @return string
*/
public function getToken()
{
return $this->token;
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace Meritoo\LimeSurvey\ApiClient\Base\Result;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Method\DisabledMethodException;
/**
* Base class for participants' collection
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class BaseParticipantsCollection extends Collection
{
/**
* {@inheritdoc}
*/
public function add($element, $index = null)
{
throw DisabledMethodException::create(__METHOD__, 'addParticipant');
}
/**
* {@inheritdoc}
*/
public function addMultiple($elements, $useIndexes = false)
{
throw DisabledMethodException::create(__METHOD__, 'addParticipants');
}
/**
* {@inheritdoc}
*/
public function has($element)
{
throw DisabledMethodException::create(__METHOD__, 'hasParticipantsOfSurvey');
}
/**
* Adds participants of given survey
*
* @param Collection $participants Participants to add. Collection of ParticipantShort or Participant instances.
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipants(Collection $participants, $surveyId)
{
/*
* No participants?
* Nothing to do
*/
if ($participants->isEmpty()) {
return $this;
}
$this
->getBySurvey($surveyId)
->addMultiple($participants);
return $this;
}
/**
* Returns participants of given survey
*
* If there are no participants of given survey, adds an empty collection who will store participants.
* So, this method will return collection always.
*
* @param int $surveyId ID of survey
* @return Collection
*/
public function getBySurvey($surveyId)
{
/*
* There are no participants of given survey?
* Let's add an empty collection who will store participants
*/
if (!isset($this[$surveyId])) {
$this[$surveyId] = new Collection();
}
return $this[$surveyId];
}
/**
* Returns information if there are participants of given survey
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasParticipantsOfSurvey($surveyId)
{
return false === $this
->getBySurvey($surveyId)
->isEmpty();
}
/**
* Adds participant of given survey
*
* @param BaseParticipant $participant Participant to add
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipant(BaseParticipant $participant, $surveyId)
{
$this
->getBySurvey($surveyId)
->add($participant);
return $this;
}
/**
* Returns participant of given survey
*
* @param int $surveyId ID of survey
* @param string $participantEmail E-mail of searched participant
* @return BaseParticipant|null
*/
public function getParticipantOfSurvey($surveyId, $participantEmail)
{
$participants = $this->getBySurvey($surveyId);
/*
* No participants?
* Nothing to do
*/
if ($participants->isEmpty()) {
return null;
}
foreach ($participants as $participant) {
if ($participant->getEmail() == $participantEmail) {
return $participant;
}
}
return null;
}
}

View File

@@ -77,6 +77,7 @@ class ConnectionConfiguration
* turned off. * turned off.
* @param bool $verifySslCertificate (optional) If is set to true, the SSL certificate verification is turned * @param bool $verifySslCertificate (optional) If is set to true, the SSL certificate verification is turned
* on. Otherwise - turned off. * on. Otherwise - turned off.
* @throws InvalidUrlException
*/ */
public function __construct($baseUrl, $username, $password, $debugMode = false, $verifySslCertificate = true) public function __construct($baseUrl, $username, $password, $debugMode = false, $verifySslCertificate = true)
{ {

View File

@@ -0,0 +1,31 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Exception;
/**
* An exception used when survey's summary is missing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MissingSurveySummaryException extends \Exception
{
/**
* Class constructor
*
* @param int $surveyId ID of survey
*/
public function __construct($surveyId)
{
$template = 'Summary of survey with ID %d is missing. Does the survey exist?';
$message = sprintf($template, $surveyId);
parent::__construct($message);
}
}

View File

@@ -20,10 +20,16 @@ use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
class UnknownMethodException extends UnknownTypeException class UnknownMethodException extends UnknownTypeException
{ {
/** /**
* {@inheritdoc} * Creates exception
*
* @param string $unknownMethod Name of unknown method used while talking to the LimeSurvey's API
* @return UnknownMethodException
*/ */
public function __construct($unknownType) public static function createException($unknownMethod)
{ {
parent::__construct($unknownType, new MethodType(), 'name of method used while talking to the LimeSurvey\'s API'); /* @var UnknownMethodException $exception */
$exception = parent::create($unknownMethod, new MethodType(), 'name of method used while talking to the LimeSurvey\'s API');
return $exception;
} }
} }

View File

@@ -8,12 +8,10 @@
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection; namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\Common\Collection\Collection; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipantsCollection;
use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
/** /**
* Collection of participants (of surveys). * Collection of participants' short data.
* All participants grouped per survey. * All participants grouped per survey.
* *
* It's a collection of participants' collections. * It's a collection of participants' collections.
@@ -22,130 +20,6 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class Participants extends Collection class Participants extends BaseParticipantsCollection
{ {
/**
* {@inheritdoc}
*/
public function add($element, $index = null)
{
throw new DisabledMethodException(__METHOD__, 'addParticipants');
}
/**
* {@inheritdoc}
*/
public function addMultiple($elements, $useIndexes = false)
{
throw new DisabledMethodException(__METHOD__, 'addParticipants');
}
/**
* {@inheritdoc}
*/
public function has($element)
{
throw new DisabledMethodException(__METHOD__, 'hasParticipantsOfSurvey');
}
/**
* Adds participants of given survey
*
* @param Collection $participants Participants to add. Collection of ParticipantShort classes.
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipants(Collection $participants, $surveyId)
{
/*
* No participants?
* Nothing to do
*/
if ($participants->isEmpty()) {
return $this;
}
$this
->getBySurvey($surveyId)
->addMultiple($participants);
return $this;
}
/**
* Adds participant of given survey
*
* @param ParticipantShort $participant Participant to add
* @param int $surveyId ID of survey
* @return $this
*/
public function addParticipant(ParticipantShort $participant, $surveyId)
{
$this
->getBySurvey($surveyId)
->add($participant);
return $this;
}
/**
* Returns information if there are participants of given survey
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasParticipantsOfSurvey($surveyId)
{
return false === $this
->getBySurvey($surveyId)
->isEmpty();
}
/**
* Returns participants of given survey
*
* If there are no participants of given survey, adds an empty collection who will store participants.
* So, this method will return collection always.
*
* @param int $surveyId ID of survey
* @return Collection
*/
public function getBySurvey($surveyId)
{
/*
* There are no participants of given survey?
* Let's add an empty collection who will store participants
*/
if (!isset($this[$surveyId])) {
$this[$surveyId] = new Collection();
}
return $this[$surveyId];
}
/**
* Returns participant of given survey
*
* @param int $surveyId ID of survey
* @param string $participantEmail E-mail of searched participant
* @return ParticipantShort|null
*/
public function getParticipantOfSurvey($surveyId, $participantEmail)
{
/* @var Collection $participants */
$participants = $this->getBySurvey($surveyId);
if ($participants->isEmpty()) {
return null;
}
/* @var ParticipantShort $participant */
foreach ($participants as $participant) {
if ($participant->getEmail() == $participantEmail) {
return $participant;
}
}
return null;
}
} }

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipantsCollection;
/**
* Collection of participants' full data.
* All participants grouped per survey.
*
* It's a collection of participants' collections.
* The survey ID is used as an index per each collection of participants, so they are grouped by survey.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ParticipantsDetails extends BaseParticipantsCollection
{
/**
* Returns information if survey with given ID has participant with given e-mail address
*
* @param int $surveyId ID of survey
* @param string $participantEmail E-mail of searched participant
* @return bool
*/
public function hasParticipantOfSurvey($surveyId, $participantEmail)
{
return null !== $this->getParticipantOfSurvey($surveyId, $participantEmail);
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Collection;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
/**
* Collection of surveys' summaries (the SurveySummary class instances)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveysSummaries extends Collection
{
/**
* {@inheritdoc}
*/
public function add($element, $index = null)
{
throw DisabledMethodException::create(__METHOD__, 'addSurveySummary');
}
/**
* {@inheritdoc}
*/
public function addMultiple($elements, $useIndexes = false)
{
throw DisabledMethodException::create(__METHOD__, 'addSurveysSummaries');
}
/**
* {@inheritdoc}
*/
public function has($element)
{
throw DisabledMethodException::create(__METHOD__, 'hasSurveySummary');
}
/**
* Adds survey's summary
*
* @param SurveySummary $summary Survey's summary
* @param int $surveyId ID of survey
* @return $this
*/
public function addSurveySummary(SurveySummary $summary, $surveyId)
{
$this[$surveyId] = $summary;
return $this;
}
/**
* Adds surveys' summaries
*
* @param array $summaries Surveys' summaries to add
* @return $this
*/
public function addSurveysSummaries(array $summaries)
{
/*
* No summaries?
* Nothing to do
*/
if (empty($summaries)) {
return $this;
}
foreach ($summaries as $surveyId => $summary) {
$this->addSurveySummary($summary, $surveyId);
}
return $this;
}
/**
* Returns information if there is summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return bool
*/
public function hasSurveySummary($surveyId)
{
/*
* There are no surveys' summaries or there is no summary of survey with given ID?
*/
if ($this->isEmpty() || !isset($this[$surveyId])) {
return false;
}
return true;
}
/**
* Returns summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return SurveySummary|null
*/
public function getSurveySummary($surveyId)
{
if ($this->hasSurveySummary($surveyId)) {
return $this[$surveyId];
}
return null;
}
}

View File

@@ -10,7 +10,7 @@ namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use DateTime; use DateTime;
use Meritoo\Common\Utilities\Date; use Meritoo\Common\Utilities\Date;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipant;
/** /**
* One item of the result/data: full data of one participant * One item of the result/data: full data of one participant
@@ -18,15 +18,8 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class Participant extends BaseItem class Participant extends BaseParticipant
{ {
/**
* ID of the participant
*
* @var int
*/
private $id;
/** /**
* Another ID of the participant? * Another ID of the participant?
* Don't know where it is used. * Don't know where it is used.
@@ -42,27 +35,6 @@ class Participant extends BaseItem
*/ */
private $mpId; private $mpId;
/**
* First name of the participant
*
* @var string
*/
private $firstName;
/**
* Last name of the participant
*
* @var string
*/
private $lastName;
/**
* E-mail of the participant
*
* @var string
*/
private $email;
/** /**
* Status of the e-mail * Status of the e-mail
* *
@@ -70,13 +42,6 @@ class Participant extends BaseItem
*/ */
private $emailStatus; private $emailStatus;
/**
* Token of the participant
*
* @var string
*/
private $token;
/** /**
* Language of the participant * Language of the participant
* *
@@ -199,7 +164,12 @@ class Participant extends BaseItem
break; break;
case 'completed': case 'completed':
$this->completed = 'Y' === trim(strtoupper($value)); if ('N' === trim(strtoupper($value))) {
$this->completed = false;
break;
}
$this->completed = Date::isValidDate($value, true);
break; break;
case 'usesleft': case 'usesleft':
@@ -211,7 +181,7 @@ class Participant extends BaseItem
break; break;
} }
$this->validFrom = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->validFrom = Date::getDateTime($value, true);
break; break;
case 'validuntil': case 'validuntil':
@@ -219,21 +189,11 @@ class Participant extends BaseItem
break; break;
} }
$this->validUntil = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->validUntil = Date::getDateTime($value, true);
break; break;
} }
} }
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/** /**
* Returns another ID of the participant? * Returns another ID of the participant?
* Don't know where it is used. * Don't know where it is used.
@@ -255,36 +215,6 @@ class Participant extends BaseItem
return $this->mpId; return $this->mpId;
} }
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/** /**
* Returns status of the e-mail * Returns status of the e-mail
* *
@@ -295,16 +225,6 @@ class Participant extends BaseItem
return $this->emailStatus; return $this->emailStatus;
} }
/**
* Returns token of the participant
*
* @return string
*/
public function getToken()
{
return $this->token;
}
/** /**
* Returns language of the participant * Returns language of the participant
* *

View File

@@ -8,7 +8,7 @@
namespace Meritoo\LimeSurvey\ApiClient\Result\Item; namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseParticipant;
/** /**
* One item of the result/data: short data of one participant * One item of the result/data: short data of one participant
@@ -16,36 +16,8 @@ use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
*/ */
class ParticipantShort extends BaseItem class ParticipantShort extends BaseParticipant
{ {
/**
* ID of the participant
*
* @var int
*/
private $id;
/**
* First name of the participant
*
* @var string
*/
private $firstName;
/**
* Last name of the participant
*
* @var string
*/
private $lastName;
/**
* E-mail of the participant
*
* @var string
*/
private $email;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@@ -56,6 +28,10 @@ class ParticipantShort extends BaseItem
$this->id = (int)$value; $this->id = (int)$value;
break; break;
case 'token':
$this->token = trim($value);
break;
case 'participant_info': case 'participant_info':
$this->firstName = trim($value['firstname']); $this->firstName = trim($value['firstname']);
$this->lastName = trim($value['lastname']); $this->lastName = trim($value['lastname']);
@@ -64,46 +40,6 @@ class ParticipantShort extends BaseItem
} }
} }
/**
* Returns ID of the participant
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Returns first name of the participant
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Returns last name of the participant
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Returns e-mail of the participant
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/** /**
* Returns short data of participant created from full data of participant * Returns short data of participant created from full data of participant
* *
@@ -120,6 +56,7 @@ class ParticipantShort extends BaseItem
$data = [ $data = [
'tid' => $participant->getId(), 'tid' => $participant->getId(),
'token' => $participant->getToken(),
'participant_info' => $info, 'participant_info' => $info,
]; ];

View File

@@ -74,7 +74,7 @@ class Survey extends BaseItem
break; break;
} }
$this->startsAt = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->startsAt = Date::getDateTime($value, true);
break; break;
case 'expires': case 'expires':
@@ -82,7 +82,7 @@ class Survey extends BaseItem
break; break;
} }
$this->expiresAt = Date::getDateTime($value, false, 'Y-m-d H:i:s'); $this->expiresAt = Date::getDateTime($value, true);
break; break;
case 'active': case 'active':

View File

@@ -0,0 +1,196 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\ApiClient\Result\Item;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
/**
* One item of the result/data: survey's summary (contains aggregated data)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveySummary extends BaseItem
{
/**
* Count/Amount of tokens
*
* @var int
*/
private $tokenCount;
/**
* Count/Amount of invalid tokens
*
* @var int
*/
private $tokenInvalidCount;
/**
* Count/Amount of sent tokens
*
* @var int
*/
private $tokenSentCount;
/**
* Count/Amount of opted out tokens
*
* @var int
*/
private $tokenOptedOutCount;
/**
* Count/Amount of completed tokens
*
* @var int
*/
private $tokenCompletedCount;
/**
* Count/Amount of complete responses
*
* @var int
*/
private $completeResponsesCount;
/**
* Count/Amount of incomplete responses
*
* @var int
*/
private $incompleteResponsesCount;
/**
* Count/Amount of full responses
*
* @var int
*/
private $fullResponsesCount;
/**
* {@inheritdoc}
*/
public function setValue($property, $value)
{
switch ($property) {
case 'token_count':
$this->tokenCount = (int)$value;
break;
case 'token_invalid':
$this->tokenInvalidCount = (int)$value;
break;
case 'token_sent':
$this->tokenSentCount = (int)$value;
break;
case 'token_opted_out':
$this->tokenOptedOutCount = (int)$value;
break;
case 'token_completed':
$this->tokenCompletedCount = (int)$value;
break;
case 'completed_responses':
$this->completeResponsesCount = (int)$value;
break;
case 'incomplete_responses':
$this->incompleteResponsesCount = (int)$value;
break;
case 'full_responses':
$this->fullResponsesCount = (int)$value;
break;
}
}
/**
* Returns count/amount of tokens
*
* @return int
*/
public function getTokenCount()
{
return $this->tokenCount;
}
/**
* Returns count/amount of invalid tokens
*
* @return int
*/
public function getTokenInvalidCount()
{
return $this->tokenInvalidCount;
}
/**
* Returns count/amount of sent tokens
*
* @return int
*/
public function getTokenSentCount()
{
return $this->tokenSentCount;
}
/**
* Returns count/amount of opted out tokens
*
* @return int
*/
public function getTokenOptedOutCount()
{
return $this->tokenOptedOutCount;
}
/**
* Returns count/amount of completed tokens
*
* @return int
*/
public function getTokenCompletedCount()
{
return $this->tokenCompletedCount;
}
/**
* Returns count/amount of complete responses
*
* @return int
*/
public function getCompleteResponsesCount()
{
return $this->completeResponsesCount;
}
/**
* Returns count/amount of incomplete responses
*
* @return int
*/
public function getIncompleteResponsesCount()
{
return $this->incompleteResponsesCount;
}
/**
* Returns count/amount of full responses
*
* @return int
*/
public function getFullResponsesCount()
{
return $this->fullResponsesCount;
}
}

View File

@@ -17,6 +17,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Question; use Meritoo\LimeSurvey\ApiClient\Result\Item\Question;
use Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort; use Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/** /**
@@ -95,6 +96,10 @@ class ResultProcessor
$className = Question::class; $className = Question::class;
break; break;
case MethodType::GET_SUMMARY:
$className = SurveySummary::class;
break;
case MethodType::LIST_PARTICIPANTS: case MethodType::LIST_PARTICIPANTS:
$className = ParticipantShort::class; $className = ParticipantShort::class;
break; break;

View File

@@ -8,13 +8,11 @@
namespace Meritoo\LimeSurvey\ApiClient\Service; namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\Common\Collection\Collection;
use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants; use Meritoo\LimeSurvey\ApiClient\Result\Collection\ParticipantsDetails;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
@@ -34,28 +32,30 @@ class ParticipantService
private $client; private $client;
/** /**
* Collection of participants (of surveys). * Collection of participants' full data.
* All participants grouped per survey. * All participants grouped per survey.
* *
* @var Participants * @var ParticipantsDetails
*/ */
private $allParticipants; private $participantsDetails;
/** /**
* Class constructor * Class constructor
* *
* @param Client $client Client of the LimeSurvey's API * @param Client $client Client of the LimeSurvey's API
* @param Participants $allParticipants (optional) Collection of participants (of surveys). All participants * @param ParticipantsDetails $participantsDetails (optional) Collection of participants' full data. All
* grouped per survey. * participants grouped per survey.
*/ */
public function __construct(Client $client, Participants $allParticipants = null) public function __construct(
{ Client $client,
if (null === $allParticipants) { ParticipantsDetails $participantsDetails = null
$allParticipants = new Participants(); ) {
if (null === $participantsDetails) {
$participantsDetails = new ParticipantsDetails();
} }
$this->client = $client; $this->client = $client;
$this->allParticipants = $allParticipants; $this->participantsDetails = $participantsDetails;
} }
/** /**
@@ -68,54 +68,6 @@ class ParticipantService
return $this->client; return $this->client;
} }
/**
* Returns participants of given survey
*
* @param int $surveyId ID of survey
* @return Collection
*
* @throws CannotProcessDataException
*/
public function getSurveyParticipants($surveyId)
{
$hasSurvey = $this
->allParticipants
->hasParticipantsOfSurvey($surveyId);
if (!$hasSurvey) {
$arguments = [
$surveyId,
];
try {
$participants = $this
->client
->run(MethodType::LIST_PARTICIPANTS, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
$reason = $exception->getReason();
/*
* Reason of the exception is different than "Oops, there is no participants. Everything else is fine."?
* Let's throw the exception
*/
if (ReasonType::NO_PARTICIPANTS_FOUND !== $reason) {
throw $exception;
}
$participants = new Collection();
}
$this
->allParticipants
->addParticipants($participants, $surveyId);
}
return $this
->allParticipants
->getBySurvey($surveyId);
}
/** /**
* Returns information if given survey has participant with given e-mail * Returns information if given survey has participant with given e-mail
* *
@@ -125,100 +77,54 @@ class ParticipantService
*/ */
public function hasParticipant($surveyId, $email) public function hasParticipant($surveyId, $email)
{ {
/* return null !== $this->getParticipantDetails($surveyId, $email);
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
return null !== $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
} }
/** /**
* Adds participant with given data to survey with given ID * Returns full data of participant with given e-mail (participant of given survey)
*
* @param int $surveyId ID of survey
* @param string $firstName First name of the participant to add
* @param string $lastName Last ame of the participant to add
* @param string $email E-mail address of the participant to add
* @return Participant
*/
public function addParticipant($surveyId, $firstName, $lastName, $email)
{
$participantsData = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$arguments = [
$surveyId,
$participantsData,
];
$participantCollection = $this
->client
->run(MethodType::ADD_PARTICIPANTS, $arguments)
->getData();
/* @var Participant $addedParticipant */
$addedParticipant = $participantCollection->getFirst();
$participants = new Collection([
ParticipantShort::fromParticipant($addedParticipant),
]);
$this
->allParticipants
->addParticipants($participants, $surveyId);
return $participantCollection->getFirst();
}
/**
* Returns short data of one participant with given e-mail of given survey
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return ParticipantShort|null
*/
public function getParticipant($surveyId, $email)
{
/*
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
return $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
}
/**
* Returns full data of participant with given e-mail of given survey
* *
* @param int $surveyId ID of survey * @param int $surveyId ID of survey
* @param string $email E-mail address of the participant * @param string $email E-mail address of the participant
* @return Participant|null * @return Participant|null
*
* @throws CannotProcessDataException
*/ */
public function getParticipantDetails($surveyId, $email) public function getParticipantDetails($surveyId, $email)
{ {
$arguments = [ if (!$this->participantsDetails->hasParticipantOfSurvey($surveyId, $email)) {
$surveyId, $participant = null;
[
'email' => $email, $arguments = [
], $surveyId,
]; [
'email' => $email,
],
];
try {
/* @var Participant $participant */
$participant = $this
->client
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
/*
* Oops, something is broken, because the reason is different than "participant was not found"
*/
if (ReasonType::NO_PARTICIPANT_PROPERTIES !== $exception->getReason()) {
throw $exception;
}
}
if (null !== $participant) {
$this->participantsDetails->addParticipant($participant, $surveyId);
}
}
$participant = $this $participant = $this
->client ->participantsDetails
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments) ->getParticipantOfSurvey($surveyId, $email);
->getData();
/* @var Participant $participant */
return $participant; return $participant;
} }
@@ -234,20 +140,9 @@ class ParticipantService
public function hasParticipantFilledSurvey($surveyId, $email) public function hasParticipantFilledSurvey($surveyId, $email)
{ {
if ($this->hasParticipant($surveyId, $email)) { if ($this->hasParticipant($surveyId, $email)) {
$arguments = [ return true === $this
$surveyId, ->getParticipantDetails($surveyId, $email)
[ ->isCompleted();
'email' => $email,
],
];
/* @var Participant $participant */
$participant = $this
->client
->run(MethodType::GET_PARTICIPANT_PROPERTIES, $arguments)
->getData();
return true === $participant->isCompleted();
} }
throw new MissingParticipantOfSurveyException($surveyId, $email); throw new MissingParticipantOfSurveyException($surveyId, $email);

View File

@@ -11,14 +11,21 @@ namespace Meritoo\LimeSurvey\ApiClient\Service;
use Meritoo\Common\Collection\Collection; use Meritoo\Common\Collection\Collection;
use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownInstanceOfResultItem;
use Meritoo\LimeSurvey\ApiClient\Exception\UnknownMethodException;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys; use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\SurveysSummaries;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
/** /**
* Service that serves surveys * Service that serves surveys and participants of surveys
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
@@ -40,6 +47,21 @@ class SurveyService
*/ */
private $allSurveys; private $allSurveys;
/**
* Collection of participants' short data.
* All participants grouped per survey.
*
* @var Participants
*/
private $allParticipants;
/**
* Collection of surveys' summaries (the SurveySummary class instances)
*
* @var SurveysSummaries
*/
private $surveySummaries;
/** /**
* Template of the url used to start survey * Template of the url used to start survey
* *
@@ -56,17 +78,36 @@ class SurveyService
/** /**
* Class constructor * Class constructor
* *
* @param Client $client Client of the LimeSurvey's API * @param Client $client Client of the LimeSurvey's API
* @param Surveys $allSurveys (optional) All surveys. Collection of surveys (the Survey class instances). * @param Surveys $allSurveys (optional) All surveys. Collection of surveys (the Survey class
* instances).
* @param Participants $allParticipants (optional) Collection of participants' short data. All participants
* grouped per survey.
* @param SurveysSummaries $surveysSummaries (optional) Collection of surveys' summaries (the SurveySummary class
* instances)
*/ */
public function __construct(Client $client, Surveys $allSurveys = null) public function __construct(
{ Client $client,
Surveys $allSurveys = null,
Participants $allParticipants = null,
SurveysSummaries $surveysSummaries = null
) {
if (null === $allSurveys) { if (null === $allSurveys) {
$allSurveys = new Surveys(); $allSurveys = new Surveys();
} }
if (null === $allParticipants) {
$allParticipants = new Participants();
}
if (null === $surveysSummaries) {
$surveysSummaries = new SurveysSummaries();
}
$this->client = $client; $this->client = $client;
$this->allSurveys = $allSurveys; $this->allSurveys = $allSurveys;
$this->allParticipants = $allParticipants;
$this->surveySummaries = $surveysSummaries;
} }
/** /**
@@ -82,10 +123,13 @@ class SurveyService
/** /**
* Returns all surveys * Returns all surveys
* *
* @param bool $onlyActive (optional) If is set to true, active surveys are returned only. Otherwise - all. * @param bool $onlyActive (optional) If is set to true, active surveys are returned only. Otherwise - all (default
* behaviour).
* @return Surveys * @return Surveys
* *
* @throws CannotProcessDataException * @throws CannotProcessDataException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/ */
public function getAllSurveys($onlyActive = false) public function getAllSurveys($onlyActive = false)
{ {
@@ -120,10 +164,13 @@ class SurveyService
/** /**
* Returns information if survey with given ID exists * Returns information if survey with given ID exists
* *
* @param int $surveyId ID of survey to verify * @param int $surveyId ID of survey to verify
* @param bool $shouldBeActive (optional) If is set to true, survey should be active. If it's not, it shouldn't * @param bool $shouldBeActive (optional) If is set to true, survey should be active. If it's not, it shouldn't
* be returned, even if exists. Otherwise - it doesn't matter. * be returned, even if exists. Otherwise - it doesn't matter (default behaviour).
* @return bool * @return bool
* @throws CannotProcessDataException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/ */
public function isExistingSurvey($surveyId, $shouldBeActive = false) public function isExistingSurvey($surveyId, $shouldBeActive = false)
{ {
@@ -149,6 +196,23 @@ class SurveyService
return false; return false;
} }
/**
* Returns url used to start survey for given survey and participant's token
*
* @param int $surveyId ID of survey to start
* @param string $participantToken Token of participant who would like to start survey
* @return string
*/
public function getStartSurveyUrlByToken($surveyId, $participantToken)
{
$baseUrl = $this
->client
->getConfiguration()
->getBaseUrl();
return sprintf($this->startSurveyUrlTemplate, $baseUrl, $surveyId, $participantToken);
}
/** /**
* Returns url used to start survey for given survey and participant * Returns url used to start survey for given survey and participant
* *
@@ -158,11 +222,240 @@ class SurveyService
*/ */
public function getStartSurveyUrl($surveyId, Participant $participant) public function getStartSurveyUrl($surveyId, Participant $participant)
{ {
$baseUrl = $this return $this->getStartSurveyUrlByToken($surveyId, $participant->getToken());
->client }
->getConfiguration()
->getBaseUrl();
return sprintf($this->startSurveyUrlTemplate, $baseUrl, $surveyId, $participant->getToken()); /**
* Returns participants of given survey
*
* @param int $surveyId ID of survey
* @param bool $onlyCompleted (optional) If is set to true, participants who completed survey are returned only.
* Otherwise - all (default behaviour).
* @return Collection
*
* @throws CannotProcessDataException
* @throws MissingSurveySummaryException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
public function getSurveyParticipants($surveyId, $onlyCompleted = false)
{
$hasSurvey = $this
->allParticipants
->hasParticipantsOfSurvey($surveyId);
if (!$hasSurvey) {
$offset = 0;
$limit = $this->getSurveyTokenCount($surveyId);
$includeUnused = !$onlyCompleted;
$arguments = [
$surveyId,
$offset,
$limit,
$includeUnused,
];
try {
$participants = $this
->client
->run(MethodType::LIST_PARTICIPANTS, $arguments)
->getData();
} catch (CannotProcessDataException $exception) {
/*
* Oops, something is broken, because the reason is different than "there are no participants"
*/
if (ReasonType::NO_PARTICIPANTS_FOUND !== $exception->getReason()) {
throw $exception;
}
$participants = new Collection();
}
$this
->allParticipants
->addParticipants($participants, $surveyId);
}
return $this
->allParticipants
->getBySurvey($surveyId);
}
/**
* Adds participant with given data to survey with given ID
*
* @param int $surveyId ID of survey
* @param string $firstName First name of the participant to add
* @param string $lastName Last ame of the participant to add
* @param string $email E-mail address of the participant to add
* @return Participant
* @throws CannotProcessDataException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
public function addParticipant($surveyId, $firstName, $lastName, $email)
{
$participantsData = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$arguments = [
$surveyId,
$participantsData,
];
$participantCollection = $this
->client
->run(MethodType::ADD_PARTICIPANTS, $arguments)
->getData();
/* @var Participant $addedParticipant */
$addedParticipant = $participantCollection->getFirst();
$participants = new Collection([
ParticipantShort::fromParticipant($addedParticipant),
]);
$this
->allParticipants
->addParticipants($participants, $surveyId);
return $participantCollection->getFirst();
}
/**
* Returns short data of one participant with given e-mail (participant of given survey)
*
* @param int $surveyId ID of survey
* @param string $email E-mail address of the participant
* @return ParticipantShort|null
* @throws CannotProcessDataException
* @throws MissingSurveySummaryException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
public function getParticipant($surveyId, $email)
{
/*
* I have to get all participants of survey to avoid problem when participants exist but are not loaded
*/
$this->getSurveyParticipants($surveyId);
$participant = $this
->allParticipants
->getParticipantOfSurvey($surveyId, $email);
/* @var ParticipantShort $participant */
return $participant;
}
/**
* Returns count/amount of tokens of survey with given ID
*
* @param int $surveyId ID of survey
* @return int
*
* @throws CannotProcessDataException
* @throws MissingSurveySummaryException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
public function getSurveyTokenCount($surveyId)
{
$surveySummary = $this
->surveySummaries
->getSurveySummary($surveyId);
/*
* Unknown survey's summary?
* Let's fetch it
*/
if (null === $surveySummary) {
$surveySummary = $this->getSurveySummary($surveyId);
}
/*
* Oops, survey's summary is missing
*/
if (null === $surveySummary) {
throw new MissingSurveySummaryException($surveyId);
}
return $surveySummary->getTokenCount();
}
/**
* Returns summary of survey with given ID
*
* @param int $surveyId ID of survey
* @return SurveySummary|null
* @throws CannotProcessDataException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
private function getSurveySummary($surveyId)
{
$arguments = [
$surveyId,
];
/* @var SurveySummary $surveySummary */
$surveySummary = $this
->client
->run(MethodType::GET_SUMMARY, $arguments)
->getData();
if (null !== $surveySummary) {
$this
->surveySummaries
->addSurveySummary($surveySummary, $surveyId);
}
return $surveySummary;
}
/**
* @param $surveyId
* @param $email
* @return bool
* @throws CannotProcessDataException
* @throws UnknownInstanceOfResultItem
* @throws UnknownMethodException
*/
public function hasSurveyBeenCompletedByEmail($surveyId, $email)
{
$arguments = [
$surveyId,
$offset = 0,
$limit = 10,
$includeUnused = false,
['completed'],
['email' => $email]
];
try {
/** @var Collection $participants */
$participants = $this
->client
->run(MethodType::LIST_PARTICIPANTS, $arguments)
->getData(true);
foreach ($participants as $participant) {
if ('N' !== $participant['completed']) {
return true;
}
}
} catch (CannotProcessDataException $exception) {
if (ReasonType::NO_PARTICIPANTS_FOUND !== $exception->getReason()) {
throw $exception;
}
}
return false;
} }
} }

View File

@@ -58,6 +58,13 @@ class MethodType extends BaseType
*/ */
const GET_QUESTION_PROPERTIES = 'get_question_properties'; const GET_QUESTION_PROPERTIES = 'get_question_properties';
/**
* Get survey summary, regarding token usage and survey participation
*
* @var string
*/
const GET_SUMMARY = 'get_summary';
/** /**
* Return the IDs and properties of token/participants of a survey * Return the IDs and properties of token/participants of a survey
* *

View File

@@ -26,6 +26,13 @@ class ReasonType extends BaseType
*/ */
const NO_PARTICIPANTS_FOUND = 'No survey participants found.'; const NO_PARTICIPANTS_FOUND = 'No survey participants found.';
/**
* Reason of exception when there is no participant's properties/details
*
* @var string
*/
const NO_PARTICIPANT_PROPERTIES = 'Error: No results were found based on your attributes.';
/** /**
* Reason of exception when there is no surveys * Reason of exception when there is no surveys
* *

View File

@@ -45,7 +45,7 @@ class ClientTest extends BaseTestCase
*/ */
public function testRunWithIncorrectMethod($incorrectMethod) public function testRunWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException(UnknownMethodException::class);
$client = new Client($this->configuration); $client = new Client($this->configuration);
$client->run($incorrectMethod); $client->run($incorrectMethod);
@@ -61,8 +61,8 @@ class ClientTest extends BaseTestCase
*/ */
public function testRun($method, $arguments, $debugMode, $expectedRawData) public function testRun($method, $arguments, $debugMode, $expectedRawData)
{ {
$sessionManager = $this->createMock(SessionManager::class); $sessionManager = $this->getMock(SessionManager::class, [], [], '', false);
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$rpcClientManager $rpcClientManager
->expects(static::any()) ->expects(static::any())

View File

@@ -47,7 +47,7 @@ class ConnectionConfigurationTest extends BaseTestCase
*/ */
public function testConstructorWithEmptyBaseUrl($emptyBaseUrl) public function testConstructorWithEmptyBaseUrl($emptyBaseUrl)
{ {
$this->expectException(InvalidUrlException::class); $this->setExpectedException(InvalidUrlException::class);
new ConnectionConfiguration($emptyBaseUrl, '', ''); new ConnectionConfiguration($emptyBaseUrl, '', '');
} }
@@ -57,7 +57,7 @@ class ConnectionConfigurationTest extends BaseTestCase
*/ */
public function testConstructorWithInvalidBaseUrl($invalidBaseUrl) public function testConstructorWithInvalidBaseUrl($invalidBaseUrl)
{ {
$this->expectException(InvalidUrlException::class); $this->setExpectedException(InvalidUrlException::class);
new ConnectionConfiguration($invalidBaseUrl, '', ''); new ConnectionConfiguration($invalidBaseUrl, '', '');
} }

View File

@@ -8,6 +8,7 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception; namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
@@ -38,6 +39,11 @@ class MissingParticipantOfSurveyExceptionTest extends BaseTestCase
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }
/**
* Provides ID of survey and e-mail address of the participant
*
* @return Generator
*/
public function provideSurveyIdAndEmail() public function provideSurveyIdAndEmail()
{ {
$template = 'Participant with e-mail %s of survey with ID %s is missing. Maybe was not added to the survey?'; $template = 'Participant with e-mail %s of survey with ID %s is missing. Maybe was not added to the survey?';

View File

@@ -0,0 +1,60 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Exception;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
/**
* Test case of an exception used when survey's summary is missing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MissingSurveySummaryExceptionTest extends BaseTestCase
{
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(MissingSurveySummaryException::class, OopVisibilityType::IS_PUBLIC, 1, 1);
}
/**
* @param int $surveyId ID of survey
* @param string $expectedMessage Expected exception's message
*
* @dataProvider provideSurveyId
*/
public function testConstructorMessage($surveyId, $expectedMessage)
{
$exception = new MissingSurveySummaryException($surveyId);
static::assertEquals($expectedMessage, $exception->getMessage());
}
/**
* Provides ID of survey
*
* @return Generator
*/
public function provideSurveyId()
{
$template = 'Summary of survey with ID %d is missing. Does the survey exist?';
yield[
1,
sprintf($template, 1),
];
yield[
'123',
sprintf($template, '123'),
];
}
}

View File

@@ -24,7 +24,7 @@ class UnknownMethodExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownMethodException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(UnknownMethodException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -35,7 +35,7 @@ class UnknownMethodExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($unknownType, $expectedMessage) public function testConstructorMessage($unknownType, $expectedMessage)
{ {
$exception = new UnknownMethodException($unknownType); $exception = UnknownMethodException::createException($unknownType);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -40,7 +40,7 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testRunMethodWithEmptyArrayReturned() public function testRunMethodWithEmptyArrayReturned()
{ {
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->getMock(RpcClient::class);
$manager = $this $manager = $this
->getMockBuilder(JsonRpcClientManager::class) ->getMockBuilder(JsonRpcClientManager::class)
@@ -68,8 +68,8 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testRunMethodWithRawDataReturned() public function testRunMethodWithRawDataReturned()
{ {
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->getMock(RpcClient::class);
$manager = $this->createPartialMock(JsonRpcClientManager::class, ['getRpcClient']); $manager = $this->getMock(JsonRpcClientManager::class, ['getRpcClient'], [], '', false);
$rpcClient $rpcClient
->expects(static::once()) ->expects(static::once())
@@ -87,10 +87,10 @@ class JsonRpcClientManagerTest extends BaseTestCase
public function testRunMethodWithException() public function testRunMethodWithException()
{ {
$this->expectException(InvalidResultOfMethodRunException::class); $this->setExpectedException(InvalidResultOfMethodRunException::class);
$manager = $this->createPartialMock(JsonRpcClientManager::class, ['getRpcClient']); $manager = $this->getMock(JsonRpcClientManager::class, ['getRpcClient'], [], '', false);
$rpcClient = $this->createMock(RpcClient::class); $rpcClient = $this->getMock(RpcClient::class);
$rpcClient $rpcClient
->expects(self::once()) ->expects(self::once())

View File

@@ -29,10 +29,9 @@ class SessionManagerTest extends BaseTestCase
public function testGetSessionKeyWhenFailedWithoutReason() public function testGetSessionKeyWhenFailedWithoutReason()
{ {
$this->expectException(CreateSessionKeyFailedException::class); $this->setExpectedException(CreateSessionKeyFailedException::class, 'Create of the session key has failed');
$this->expectExceptionMessage('Create of the session key has failed');
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -46,10 +45,10 @@ class SessionManagerTest extends BaseTestCase
{ {
$reason = 'Invalid credentials'; $reason = 'Invalid credentials';
$this->expectException(CreateSessionKeyFailedException::class); $message = sprintf('Create of the session key has failed. Reason: \'%s\'.', $reason);
$this->expectExceptionMessage(sprintf('Create of the session key has failed. Reason: \'%s\'.', $reason)); $this->setExpectedException(CreateSessionKeyFailedException::class, $message);
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -63,7 +62,7 @@ class SessionManagerTest extends BaseTestCase
public function testGetSessionKey() public function testGetSessionKey()
{ {
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())
@@ -76,7 +75,7 @@ class SessionManagerTest extends BaseTestCase
public function testReleaseSessionKey() public function testReleaseSessionKey()
{ {
$clientManager = $this->createMock(JsonRpcClientManager::class); $clientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$clientManager $clientManager
->expects(static::any()) ->expects(static::any())

0
tests/Resources/var/cache/.gitkeep vendored Normal file
View File

View File

View File

View File

@@ -17,7 +17,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort; use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
/** /**
* Test case of the collection of participants (of surveys) * Test case of the collection of participants' short data
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
@@ -25,7 +25,7 @@ use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
class ParticipantsTest extends BaseTestCase class ParticipantsTest extends BaseTestCase
{ {
/** /**
* An empty collection of participants (of surveys) * An empty collection of participants' short data
* *
* @var Participants * @var Participants
*/ */
@@ -52,19 +52,19 @@ class ParticipantsTest extends BaseTestCase
public function testAdd() public function testAdd()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::class);
(new Participants())->add(''); (new Participants())->add('');
} }
public function testAddMultiple() public function testAddMultiple()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::class);
(new Participants())->addMultiple([]); (new Participants())->addMultiple([]);
} }
public function testHas() public function testHas()
{ {
$this->expectException(DisabledMethodException::class); $this->setExpectedException(DisabledMethodException::class);
(new Participants())->has(new Participant()); (new Participants())->has(new Participant());
} }

View File

@@ -0,0 +1,174 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Collection;
use Generator;
use Meritoo\Common\Exception\Method\DisabledMethodException;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\SurveysSummaries;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
/**
* Test case of the collection of surveys' summaries (the SurveySummary class instances)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveysSummariesTest extends BaseTestCase
{
/**
* Empty collection of surveys' summaries
*
* @var SurveysSummaries
*/
private $emptySurveysSummaries;
/**
* Non-empty collection of surveys' summaries
*
* @var SurveysSummaries
*/
private $nonEmptySurveysSummaries;
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(SurveysSummaries::class, OopVisibilityType::IS_PUBLIC, 1, 0);
}
public function testAdd()
{
$this->setExpectedException(DisabledMethodException::class);
(new SurveysSummaries())->add('');
}
public function testAddMultiple()
{
$this->setExpectedException(DisabledMethodException::class);
(new SurveysSummaries())->addMultiple([]);
}
public function testHas()
{
$this->setExpectedException(DisabledMethodException::class);
(new SurveysSummaries())->has(new SurveySummary());
}
/**
* @param array $summaries Surveys' summaries to add
* @dataProvider provideSurveysSummaries
*/
public function testAddSurveysSummaries(array $summaries)
{
$existingSummariesCount = $this->nonEmptySurveysSummaries->count();
$this->emptySurveysSummaries->addSurveysSummaries($summaries);
$this->nonEmptySurveysSummaries->addSurveysSummaries($summaries);
static::assertCount(count($summaries), $this->emptySurveysSummaries);
static::assertCount(count($summaries) + $existingSummariesCount, $this->nonEmptySurveysSummaries);
}
public function testHasSurveySummaryUsingNonExistingSurvey()
{
static::assertFalse($this->emptySurveysSummaries->hasSurveySummary(1));
static::assertFalse($this->emptySurveysSummaries->hasSurveySummary(2));
static::assertFalse($this->nonEmptySurveysSummaries->hasSurveySummary(3));
static::assertFalse($this->nonEmptySurveysSummaries->hasSurveySummary(4));
}
public function testHasSurveySummaryUsingExistingSurvey()
{
static::assertTrue($this->nonEmptySurveysSummaries->hasSurveySummary(1));
static::assertTrue($this->nonEmptySurveysSummaries->hasSurveySummary(2));
}
public function testGetSurveySummaryUsingNonExistingSurvey()
{
static::assertNull($this->emptySurveysSummaries->getSurveySummary(1));
static::assertNull($this->emptySurveysSummaries->getSurveySummary(2));
static::assertNull($this->nonEmptySurveysSummaries->getSurveySummary(3));
static::assertNull($this->nonEmptySurveysSummaries->getSurveySummary(4));
}
public function testGetSurveySummaryUsingExistingSurvey()
{
$surveySummary1 = $this->nonEmptySurveysSummaries->getSurveySummary(1);
$surveySummary2 = $this->nonEmptySurveysSummaries->getSurveySummary(2);
static::assertInstanceOf(SurveySummary::class, $surveySummary1);
static::assertInstanceOf(SurveySummary::class, $surveySummary2);
static::assertEquals(0, $surveySummary1->getTokenCount());
static::assertEquals(5, $surveySummary2->getTokenCount());
static::assertEquals(0, $surveySummary1->getFullResponsesCount());
static::assertEquals(3, $surveySummary2->getFullResponsesCount());
}
/**
* Provides surveys' summaries
*
* @return Generator
*/
public function provideSurveysSummaries()
{
yield[
[],
];
yield[
[
123 => new SurveySummary(),
],
];
yield[
[
100 => new SurveySummary(),
500 => new SurveySummary(),
800 => new SurveySummary(),
],
];
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->emptySurveysSummaries = new SurveysSummaries();
$this->nonEmptySurveysSummaries = new SurveysSummaries([
1 => new SurveySummary([
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
]),
2 => new SurveySummary([
'token_count' => '5',
'token_invalid' => '2',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '2',
'completed_responses' => '1',
'incomplete_responses' => '2',
'full_responses' => '3',
]),
]);
}
}

View File

@@ -127,12 +127,24 @@ class ParticipantShortTest extends BaseTestCase
static::assertEquals($participant2->getEmail(), $participantShort2->getEmail()); static::assertEquals($participant2->getEmail(), $participantShort2->getEmail());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new ParticipantShort($this->rawData[0]);
$this->participant2ndInstance = new ParticipantShort($this->rawData[1]);
}
/** /**
* Returns raw data of participants * Returns raw data of participants
* *
* @return array * @return array
*/ */
public static function getParticipantsRawData() private static function getParticipantsRawData()
{ {
return [ return [
[ [
@@ -153,16 +165,4 @@ class ParticipantShortTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new ParticipantShort($this->rawData[0]);
$this->participant2ndInstance = new ParticipantShort($this->rawData[1]);
}
} }

View File

@@ -14,6 +14,7 @@ use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
/** /**
* Test case of the one item of the result/data: full data of participant * Test case of the one item of the result/data: full data of participant
@@ -159,12 +160,24 @@ class ParticipantTest extends BaseTestCase
static::assertNull($this->participant2ndInstance->getValidUntil()); static::assertNull($this->participant2ndInstance->getValidUntil());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new Participant($this->rawData[0]);
$this->participant2ndInstance = new Participant($this->rawData[1]);
}
/** /**
* Returns raw data of participants * Returns raw data of participants
* *
* @return array * @return array
*/ */
public static function getParticipantsRawData() private static function getParticipantsRawData()
{ {
return [ return [
[ [
@@ -184,7 +197,7 @@ class ParticipantTest extends BaseTestCase
'completed' => 'N', 'completed' => 'N',
'usesleft' => 10, 'usesleft' => 10,
'validfrom' => null, 'validfrom' => null,
'validuntil' => (new DateTime())->format('Y-m-d H:i:s'), 'validuntil' => DateUtility::getDateTime(),
], ],
[ [
'tid' => '456', 'tid' => '456',
@@ -200,23 +213,11 @@ class ParticipantTest extends BaseTestCase
'sent' => 'Y', 'sent' => 'Y',
'remindersent' => 'N', 'remindersent' => 'N',
'remindercount' => 1, 'remindercount' => 1,
'completed' => 'Y', 'completed' => DateUtility::getDateTime(false),
'usesleft' => 5, 'usesleft' => 5,
'validfrom' => (new DateTime())->format('Y-m-d H:i:s'), 'validfrom' => DateUtility::getDateTime(),
'validuntil' => null, 'validuntil' => null,
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getParticipantsRawData();
$this->participant1stInstance = new Participant($this->rawData[0]);
$this->participant2ndInstance = new Participant($this->rawData[1]);
}
} }

View File

@@ -158,12 +158,24 @@ class QuestionShortTest extends BaseTestCase
static::assertEquals('HR', $this->question2ndInstance->getModuleName()); static::assertEquals('HR', $this->question2ndInstance->getModuleName());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new QuestionShort($this->rawData[0]);
$this->question2ndInstance = new QuestionShort($this->rawData[1]);
}
/** /**
* Returns raw data of questions * Returns raw data of questions
* *
* @return array * @return array
*/ */
public static function getQuestionsRawData() private static function getQuestionsRawData()
{ {
return [ return [
[ [
@@ -214,16 +226,4 @@ class QuestionShortTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new QuestionShort($this->rawData[0]);
$this->question2ndInstance = new QuestionShort($this->rawData[1]);
}
} }

View File

@@ -194,12 +194,24 @@ class QuestionTest extends BaseTestCase
static::assertNull($this->question2ndInstance->getDefaultValue()); static::assertNull($this->question2ndInstance->getDefaultValue());
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new Question($this->rawData[0]);
$this->question2ndInstance = new Question($this->rawData[1]);
}
/** /**
* Returns raw data of questions * Returns raw data of questions
* *
* @return array * @return array
*/ */
public static function getQuestionsRawData() private static function getQuestionsRawData()
{ {
return [ return [
[ [
@@ -276,16 +288,4 @@ class QuestionTest extends BaseTestCase
], ],
]; ];
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->rawData = static::getQuestionsRawData();
$this->question1stInstance = new Question($this->rawData[0]);
$this->question2ndInstance = new Question($this->rawData[1]);
}
} }

View File

@@ -0,0 +1,97 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\SurveySummary;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
/**
* Test case of the one item of the result/data: survey's summary (contains aggregated data)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class SurveySummaryTest extends BaseTestCase
{
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(SurveySummary::class, OopVisibilityType::IS_PUBLIC, 1, 0);
}
/**
* @param array $rawData Raw data of survey's summary
* @dataProvider provideRawData
*/
public function testCreateOfTheSurveySummary(array $rawData)
{
$processor = new ResultProcessor();
$processed = $processor->process(MethodType::GET_SUMMARY, $rawData);
/* @var SurveySummary $processed */
static::assertEquals($rawData['token_count'], $processed->getTokenCount());
static::assertEquals($rawData['token_invalid'], $processed->getTokenInvalidCount());
static::assertEquals($rawData['token_sent'], $processed->getTokenSentCount());
static::assertEquals($rawData['token_opted_out'], $processed->getTokenOptedOutCount());
static::assertEquals($rawData['token_completed'], $processed->getTokenCompletedCount());
static::assertEquals($rawData['completed_responses'], $processed->getCompleteResponsesCount());
static::assertEquals($rawData['incomplete_responses'], $processed->getIncompleteResponsesCount());
static::assertEquals($rawData['full_responses'], $processed->getFullResponsesCount());
}
/**
* Provides raw data of survey's summary
*
* @return Generator
*/
public function provideRawData()
{
yield[
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
yield[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '5',
'token_opted_out' => '0',
'token_completed' => '6',
'completed_responses' => '6',
'incomplete_responses' => '10',
'full_responses' => '16',
],
];
yield[
[
'token_count' => '28',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '2',
'completed_responses' => '2',
'incomplete_responses' => '12',
'full_responses' => '14',
],
];
}
}

View File

@@ -14,6 +14,7 @@ use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
/** /**
* Test case of the one item of the result/data: survey * Test case of the one item of the result/data: survey
@@ -99,13 +100,13 @@ class SurveyTest extends BaseTestCase
'sid' => '123', 'sid' => '123',
'surveyls_title' => 'Test', 'surveyls_title' => 'Test',
'startdate' => null, 'startdate' => null,
'expires' => (new DateTime())->format('Y-m-d H:i:s'), 'expires' => DateUtility::getDateTime(),
'active' => 'N', 'active' => 'N',
], ],
[ [
'sid' => '456', 'sid' => '456',
'surveyls_title' => 'Another Test', 'surveyls_title' => 'Another Test',
'startdate' => (new DateTime())->format('Y-m-d H:i:s'), 'startdate' => DateUtility::getDateTime(),
'expires' => null, 'expires' => null,
'active' => 'Y', 'active' => 'Y',
], ],

View File

@@ -82,7 +82,7 @@ class ResultProcessorTest extends BaseTestCase
public function testRunWithUnknownResultClass() public function testRunWithUnknownResultClass()
{ {
$this->expectException(UnknownInstanceOfResultItem::class); $this->setExpectedException(UnknownInstanceOfResultItem::class);
$rawData = [ $rawData = [
'lorem' => 'ipsum', 'lorem' => 'ipsum',

View File

@@ -8,13 +8,13 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Result; namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Result;
use DateTime;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Result\Result; use Meritoo\LimeSurvey\ApiClient\Result\Result;
use Meritoo\LimeSurvey\ApiClient\Type\MethodType; use Meritoo\LimeSurvey\ApiClient\Type\MethodType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
@@ -128,7 +128,7 @@ class ResultTest extends BaseTestCase
public function testGetDataUsingProcessedDataWhoCannotBeProcessed() public function testGetDataUsingProcessedDataWhoCannotBeProcessed()
{ {
$this->expectException(CannotProcessDataException::class); $this->setExpectedException(CannotProcessDataException::class);
$this->statusInsteadDataResult->getData(); $this->statusInsteadDataResult->getData();
} }
@@ -179,7 +179,7 @@ class ResultTest extends BaseTestCase
[ [
'sid' => '456', 'sid' => '456',
'surveyls_title' => 'Another Test', 'surveyls_title' => 'Another Test',
'startdate' => (new DateTime())->format('Y-m-d H:i:s'), 'startdate' => DateUtility::getDateTime(),
'expires' => null, 'expires' => null,
'active' => 'Y', 'active' => 'Y',
], ],

View File

@@ -18,11 +18,11 @@ use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException;
use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager;
use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants; use Meritoo\LimeSurvey\ApiClient\Result\Collection\ParticipantsDetails;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Service\ParticipantService; use Meritoo\LimeSurvey\ApiClient\Service\ParticipantService;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
use Meritoo\LimeSurvey\Test\ApiClient\Utilities\DateUtility;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
@@ -33,6 +33,13 @@ use PHPUnit_Framework_MockObject_MockObject;
*/ */
class ParticipantServiceTest extends BaseTestCase class ParticipantServiceTest extends BaseTestCase
{ {
/**
* Raw data of participants
*
* @var array
*/
private $participantsRawData;
/** /**
* Service that serves participants. * Service that serves participants.
* Without participants. * Without participants.
@@ -72,124 +79,46 @@ class ParticipantServiceTest extends BaseTestCase
static::assertEquals($client, $participantService->getClient()); static::assertEquals($client, $participantService->getClient());
} }
public function testGetSurveyParticipants() public function testHasParticipantUsingServiceWithoutParticipants()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(3); $rpcClientManager = $this->getJsonRpcClientManager(2);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager); $this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(1)); static::assertFalse($this->serviceWithoutParticipants->hasParticipant(1, 'john@scott.com'));
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(2)); static::assertFalse($this->serviceWithoutParticipants->hasParticipant(2, 'john@scott.com'));
static::assertCount(2, $this->serviceWithParticipants->getSurveyParticipants(1));
static::assertCount(1, $this->serviceWithParticipants->getSurveyParticipants(2));
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testGetSurveyParticipantsWithImportantException()
{
$this->expectException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsException()
{
$exception = new CannotProcessDataException(ReasonType::NO_PARTICIPANTS_FOUND);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
} }
public function testHasParticipant() public function testHasParticipant()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(3); $runMethodCallResults = [
[
null,
],
[
null,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertFalse($this->serviceWithoutParticipants->hasParticipant(1, 'john@scott.com'));
static::assertFalse($this->serviceWithoutParticipants->hasParticipant(2, 'john@scott.com'));
static::assertTrue($this->serviceWithParticipants->hasParticipant(1, 'john@scott.com')); static::assertTrue($this->serviceWithParticipants->hasParticipant(1, 'john@scott.com'));
static::assertFalse($this->serviceWithParticipants->hasParticipant(2, 'john@scott.com')); static::assertFalse($this->serviceWithParticipants->hasParticipant(2, 'john@scott.com'));
static::assertFalse($this->serviceWithParticipants->hasParticipant(3, 'john@scott.com')); static::assertFalse($this->serviceWithParticipants->hasParticipant(3, 'john@scott.com'));
} }
public function testAddParticipantForNotExistingSurvey() public function testGetParticipantDetailsWithException()
{ {
$this->expectException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID); $exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$this->setExpectedException(CannotProcessDataException::class, $exception->getMessage());
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$surveyId = 1; $this->serviceWithParticipants->getParticipantDetails(1, 'lorem@ipsum.com');
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
$this->serviceWithParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
}
public function testAddParticipant()
{
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$runMethodCallCount = 1;
$runMethodCallResults = [
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
];
$rpcClientManager = $this->getJsonRpcClientManager($runMethodCallCount, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$result = $this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
static::assertInstanceOf(Participant::class, $result);
static::assertEquals($firstName, $result->getFirstName());
static::assertEquals($lastName, $result->getLastName());
static::assertEquals($email, $result->getEmail());
}
public function testGetParticipant()
{
$rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertNull($this->serviceWithoutParticipants->getParticipant(1, 'john@scott.com'));
$participant = $this->serviceWithParticipants->getParticipant(1, 'john@scott.com');
static::assertInstanceOf(ParticipantShort::class, $participant);
static::assertEquals('John', $participant->getFirstName());
static::assertEquals('Scott', $participant->getLastName());
static::assertEquals('john@scott.com', $participant->getEmail());
} }
public function testGetParticipantDetails() public function testGetParticipantDetails()
@@ -199,37 +128,35 @@ class ParticipantServiceTest extends BaseTestCase
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager); $this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$runMethodCallResults = [ $rpcClientManager = $this->getJsonRpcClientManager(0);
'tid' => 1,
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'token' => uniqid(),
'sent' => 'N',
'completed' => 'N',
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertNull($this->serviceWithoutParticipants->getParticipantDetails(1, 'john@scott.com')); $participant1 = $this->serviceWithoutParticipants->getParticipantDetails(1, 'john@scott.com');
$participant = $this->serviceWithParticipants->getParticipantDetails(1, 'john@scott.com'); $participant2 = $this->serviceWithParticipants->getParticipantDetails(1, 'john@scott.com');
static::assertInstanceOf(Participant::class, $participant); $rawData = $this->participantsRawData[0];
static::assertEquals($runMethodCallResults['tid'], $participant->getId()); $id = $rawData['tid'];
static::assertEquals($runMethodCallResults['firstname'], $participant->getFirstName()); $firstName = $rawData['firstname'];
static::assertEquals($runMethodCallResults['lastname'], $participant->getLastName()); $lastName = $rawData['lastname'];
static::assertEquals($runMethodCallResults['email'], $participant->getEmail()); $email = $rawData['email'];
static::assertEquals($runMethodCallResults['token'], $participant->getToken()); $token = $rawData['token'];
static::assertFalse($participant->isSent());
static::assertFalse($participant->isCompleted()); static::assertNull($participant1);
static::assertNull($participant->isBlacklisted()); static::assertInstanceOf(Participant::class, $participant2);
static::assertNull($participant->getValidFrom()); static::assertEquals($id, $participant2->getId());
static::assertEquals($firstName, $participant2->getFirstName());
static::assertEquals($lastName, $participant2->getLastName());
static::assertEquals($email, $participant2->getEmail());
static::assertEquals($token, $participant2->getToken());
static::assertTrue($participant2->isSent());
static::assertTrue($participant2->isCompleted());
static::assertFalse($participant2->isBlacklisted());
static::assertNull($participant2->getValidFrom());
} }
public function testHasParticipantFilledSurveyWithException() public function testHasParticipantFilledSurveyWithoutParticipants()
{ {
$this->expectException(MissingParticipantOfSurveyException::class); $this->setExpectedException(MissingParticipantOfSurveyException::class);
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
@@ -240,14 +167,7 @@ class ParticipantServiceTest extends BaseTestCase
public function testHasParticipantFilledSurveyUsingExistingParticipant() public function testHasParticipantFilledSurveyUsingExistingParticipant()
{ {
$runMethodCallResults = [ $rpcClientManager = $this->getJsonRpcClientManager(0);
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'completed' => 'Y',
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager); $this->createServiceWithParticipants($rpcClientManager, $sessionManager);
@@ -256,7 +176,7 @@ class ParticipantServiceTest extends BaseTestCase
public function testHasParticipantFilledSurveyUsingNotExistingParticipant() public function testHasParticipantFilledSurveyUsingNotExistingParticipant()
{ {
$this->expectException(MissingParticipantOfSurveyException::class); $this->setExpectedException(MissingParticipantOfSurveyException::class);
$rpcClientManager = $this->getJsonRpcClientManager(1); $rpcClientManager = $this->getJsonRpcClientManager(1);
$sessionManager = $this->getSessionManager(); $sessionManager = $this->getSessionManager();
@@ -265,6 +185,55 @@ class ParticipantServiceTest extends BaseTestCase
$this->serviceWithParticipants->hasParticipantFilledSurvey(3, 'mary@jane.com'); $this->serviceWithParticipants->hasParticipantFilledSurvey(3, 'mary@jane.com');
} }
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->participantsRawData = [
[
'tid' => 1,
'participant_id' => null,
'mpid' => null,
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
'emailstatus' => 'OK',
'token' => uniqid(),
'language' => 'pl',
'blacklisted' => 'N',
'sent' => 'Y',
'remindersent' => 'N',
'remindercount' => 0,
'completed' => DateUtility::getDateTime(),
'usesleft' => 10,
'validfrom' => null,
'validuntil' => DateUtility::getDateTime(),
],
[
'tid' => 2,
'participant_id' => null,
'mpid' => null,
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
'emailstatus' => 'OK',
'token' => uniqid(),
'language' => 'pl',
'blacklisted' => 'N',
'sent' => 'Y',
'remindersent' => 'N',
'remindercount' => 0,
'completed' => 'N',
'usesleft' => 10,
'validfrom' => null,
'validuntil' => DateUtility::getDateTime(),
],
];
}
/** /**
* Returns configuration used while connecting to LimeSurvey's API * Returns configuration used while connecting to LimeSurvey's API
* *
@@ -282,7 +251,7 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getSessionManager() private function getSessionManager()
{ {
return $this->createMock(SessionManager::class); return $this->getMock(SessionManager::class, [], [], '', false);
} }
/** /**
@@ -294,12 +263,24 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = []) private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = [])
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$rpcClientManager $mocker = $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
->method('runMethod') ->method('runMethod');
->will(static::returnValue($runMethodCallResults));
if (!empty($runMethodCallResults)) {
$function = [
$mocker,
'willReturnOnConsecutiveCalls',
];
/*
* I have to use the call_user_func_array() function to pass elements of $runMethodCallResults array as
* arguments of the willReturnOnConsecutiveCalls() method
*/
call_user_func_array($function, $runMethodCallResults);
}
return $rpcClientManager; return $rpcClientManager;
} }
@@ -314,7 +295,7 @@ class ParticipantServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception) private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception)
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$rpcClientManager $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
@@ -348,30 +329,16 @@ class ParticipantServiceTest extends BaseTestCase
$configuration = $this->getConnectionConfiguration(); $configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager); $client = new Client($configuration, $rpcClientManager, $sessionManager);
$allParticipants = new Participants([ $participantsDetails = new ParticipantsDetails([
1 => new Collection([ 1 => new Collection([
new ParticipantShort([ new Participant($this->participantsRawData[0]),
'tid' => 1, new Participant($this->participantsRawData[1]),
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
]),
new ParticipantShort([
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
]),
]), ]),
2 => new Collection([ 2 => new Collection([
new ParticipantShort(), new Participant(),
]), ]),
]); ]);
$this->serviceWithParticipants = new ParticipantService($client, $allParticipants); $this->serviceWithParticipants = new ParticipantService($client, $participantsDetails);
} }
} }

View File

@@ -9,22 +9,26 @@
namespace Meritoo\LimeSurvey\Test\ApiClient\Service; namespace Meritoo\LimeSurvey\Test\ApiClient\Service;
use Exception; use Exception;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Client\Client;
use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration; use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration;
use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException;
use Meritoo\LimeSurvey\ApiClient\Exception\MissingSurveySummaryException;
use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager;
use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants;
use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys; use Meritoo\LimeSurvey\ApiClient\Result\Collection\Surveys;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant;
use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort;
use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey;
use Meritoo\LimeSurvey\ApiClient\Service\SurveyService; use Meritoo\LimeSurvey\ApiClient\Service\SurveyService;
use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use Meritoo\LimeSurvey\ApiClient\Type\ReasonType;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
/** /**
* Test case of the service that serves surveys * Test case of the service that serves surveys and participants of surveys
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo.pl
@@ -32,7 +36,7 @@ use PHPUnit_Framework_MockObject_MockObject;
class SurveyServiceTest extends BaseTestCase class SurveyServiceTest extends BaseTestCase
{ {
/** /**
* Service that serves surveys. * Service that serves surveys and participants of surveys.
* Without surveys. * Without surveys.
* *
* @var SurveyService * @var SurveyService
@@ -40,13 +44,29 @@ class SurveyServiceTest extends BaseTestCase
private $serviceWithoutSurveys; private $serviceWithoutSurveys;
/** /**
* Service that serves surveys. * Service that serves surveys and participants of surveys.
* With surveys. * With surveys.
* *
* @var SurveyService * @var SurveyService
*/ */
private $serviceWithSurveys; private $serviceWithSurveys;
/**
* Service that serves surveys and participants of surveys.
* Without participants.
*
* @var SurveyService
*/
private $serviceWithoutParticipants;
/**
* Service that serves surveys and participants of surveys.
* With participants.
*
* @var SurveyService
*/
private $serviceWithParticipants;
/** /**
* Base url of LimeSurvey's instance. * Base url of LimeSurvey's instance.
* Used to prepare configuration of connection. * Used to prepare configuration of connection.
@@ -57,7 +77,7 @@ class SurveyServiceTest extends BaseTestCase
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(SurveyService::class, OopVisibilityType::IS_PUBLIC, 2, 1); static::assertConstructorVisibilityAndArguments(SurveyService::class, OopVisibilityType::IS_PUBLIC, 4, 1);
} }
public function testGetClient() public function testGetClient()
@@ -78,9 +98,9 @@ class SurveyServiceTest extends BaseTestCase
static::assertEquals($client, $surveyService->getClient()); static::assertEquals($client, $surveyService->getClient());
} }
public function testGetAllSurveysWithImportantException() public function testGetAllSurveysWithNoTableException()
{ {
$this->expectException(CannotProcessDataException::class); $this->setExpectedException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE); $exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
@@ -161,6 +181,22 @@ class SurveyServiceTest extends BaseTestCase
static::assertFalse($this->serviceWithSurveys->isExistingSurvey(4, true)); static::assertFalse($this->serviceWithSurveys->isExistingSurvey(4, true));
} }
public function testGetStartSurveyUrlByToken()
{
$rpcClientManager = $this->getJsonRpcClientManager(0);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutSurveys($rpcClientManager, $sessionManager);
$this->createServiceWithSurveys($rpcClientManager, $sessionManager);
$surveyId = 123;
$token = uniqid();
$expectedUrl = sprintf('%s/%d?token=%s', $this->connectionBaseUrl, $surveyId, $token);
static::assertEquals($expectedUrl, $this->serviceWithoutSurveys->getStartSurveyUrlByToken($surveyId, $token));
static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrlByToken($surveyId, $token));
}
public function testGetStartSurveyUrl() public function testGetStartSurveyUrl()
{ {
$rpcClientManager = $this->getJsonRpcClientManager(0); $rpcClientManager = $this->getJsonRpcClientManager(0);
@@ -185,6 +221,262 @@ class SurveyServiceTest extends BaseTestCase
static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrl($surveyId, $participant)); static::assertEquals($expectedUrl, $this->serviceWithSurveys->getStartSurveyUrl($surveyId, $participant));
} }
public function testGetSurveyParticipantsWithNotExistingSurveyException()
{
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$this->setExpectedException(CannotProcessDataException::class, $exception->getMessage());
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
[
'status' => ReasonType::NOT_EXISTING_SURVEY_ID,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsFoundException()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
[
'status' => ReasonType::NO_PARTICIPANTS_FOUND,
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$participants = $this->serviceWithParticipants->getSurveyParticipants(3);
static::assertInstanceOf(Collection::class, $participants);
static::assertCount(0, $participants);
}
public function testGetSurveyParticipants()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
'token_count' => '2',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
$rpcClientManager = $this->getJsonRpcClientManager(6, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(1));
static::assertCount(0, $this->serviceWithoutParticipants->getSurveyParticipants(2));
static::assertCount(2, $this->serviceWithParticipants->getSurveyParticipants(1));
static::assertCount(1, $this->serviceWithParticipants->getSurveyParticipants(2));
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testGetSurveyParticipantsWithNoTableException()
{
$this->setExpectedException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$this->serviceWithParticipants->getSurveyParticipants(3);
}
public function testGetSurveyParticipantsWithNoParticipantsException()
{
$this->setExpectedException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NO_PARTICIPANTS_FOUND);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3));
}
public function testAddParticipantForNotExistingSurvey()
{
$this->setExpectedException(CannotProcessDataException::class);
$exception = new CannotProcessDataException(ReasonType::NOT_EXISTING_SURVEY_ID);
$rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
$this->serviceWithParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
}
public function testAddParticipant()
{
$surveyId = 1;
$firstName = 'John';
$lastName = 'Scott';
$email = 'john@scott.com';
$runMethodCallCount = 1;
$runMethodCallResults = [
[
[
'firstname' => $firstName,
'lastname' => $lastName,
'email' => $email,
],
],
];
$rpcClientManager = $this->getJsonRpcClientManager($runMethodCallCount, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$result = $this->serviceWithoutParticipants->addParticipant($surveyId, $firstName, $lastName, $email);
static::assertInstanceOf(Participant::class, $result);
static::assertEquals($firstName, $result->getFirstName());
static::assertEquals($lastName, $result->getLastName());
static::assertEquals($email, $result->getEmail());
}
public function testGetParticipant()
{
$runMethodCallResults = [
[
'token_count' => '0',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
null,
[
[
'tid' => 1,
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
],
[
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
],
],
[
'token_count' => '2',
'token_invalid' => '0',
'token_sent' => '0',
'token_opted_out' => '0',
'token_completed' => '0',
'completed_responses' => '0',
'incomplete_responses' => '0',
'full_responses' => '0',
],
];
$rpcClientManager = $this->getJsonRpcClientManager(2, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutParticipants($rpcClientManager, $sessionManager);
$this->createServiceWithParticipants($rpcClientManager, $sessionManager);
$participant1 = $this->serviceWithoutParticipants->getParticipant(1, 'john@scott.com');
$participant2 = $this->serviceWithParticipants->getParticipant(1, 'john@scott.com');
static::assertNull($participant1);
static::assertInstanceOf(ParticipantShort::class, $participant2);
static::assertEquals('John', $participant2->getFirstName());
static::assertEquals('Scott', $participant2->getLastName());
static::assertEquals('john@scott.com', $participant2->getEmail());
}
public function testGetSurveyTokenCountWithException()
{
$this->setExpectedException(MissingSurveySummaryException::class);
$runMethodCallResults = [
null,
];
$rpcClientManager = $this->getJsonRpcClientManager(1, $runMethodCallResults);
$sessionManager = $this->getSessionManager();
$this->createServiceWithoutSurveys($rpcClientManager, $sessionManager);
$this->serviceWithoutSurveys->getSurveyTokenCount(1);
}
/** /**
* Returns configuration used while connecting to LimeSurvey's API * Returns configuration used while connecting to LimeSurvey's API
* *
@@ -202,7 +494,7 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getSessionManager() private function getSessionManager()
{ {
return $this->createMock(SessionManager::class); return $this->getMock(SessionManager::class, [], [], '', false);
} }
/** /**
@@ -214,12 +506,24 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = []) private function getJsonRpcClientManager($runMethodCallCount, array $runMethodCallResults = [])
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$rpcClientManager $mocker = $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
->method('runMethod') ->method('runMethod');
->will(static::returnValue($runMethodCallResults));
if (!empty($runMethodCallResults)) {
$function = [
$mocker,
'willReturnOnConsecutiveCalls',
];
/*
* I have to use the call_user_func_array() function to pass elements of $runMethodCallResults array as
* arguments of the willReturnOnConsecutiveCalls() method
*/
call_user_func_array($function, $runMethodCallResults);
}
return $rpcClientManager; return $rpcClientManager;
} }
@@ -234,7 +538,7 @@ class SurveyServiceTest extends BaseTestCase
*/ */
private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception) private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception)
{ {
$rpcClientManager = $this->createMock(JsonRpcClientManager::class); $rpcClientManager = $this->getMock(JsonRpcClientManager::class, [], [], '', false);
$rpcClientManager $rpcClientManager
->expects(static::exactly($runMethodCallCount)) ->expects(static::exactly($runMethodCallCount))
@@ -287,4 +591,55 @@ class SurveyServiceTest extends BaseTestCase
$this->serviceWithSurveys = new SurveyService($client, $allSurveys); $this->serviceWithSurveys = new SurveyService($client, $allSurveys);
} }
/**
* Creates instance of the tested service without participants
*
* @param PHPUnit_Framework_MockObject_MockObject $rpcClientManager Manager of the JsonRPC client used while connecting to LimeSurvey's API
* @param PHPUnit_Framework_MockObject_MockObject $sessionManager Manager of session started while connecting to LimeSurvey's API
*/
private function createServiceWithoutParticipants(PHPUnit_Framework_MockObject_MockObject $rpcClientManager, PHPUnit_Framework_MockObject_MockObject $sessionManager)
{
$configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager);
$this->serviceWithoutParticipants = new SurveyService($client);
}
/**
* Creates instance of the tested service with participants
*
* @param PHPUnit_Framework_MockObject_MockObject $rpcClientManager Manager of the JsonRPC client used while connecting to LimeSurvey's API
* @param PHPUnit_Framework_MockObject_MockObject $sessionManager Manager of session started while connecting to LimeSurvey's API
*/
private function createServiceWithParticipants(PHPUnit_Framework_MockObject_MockObject $rpcClientManager, PHPUnit_Framework_MockObject_MockObject $sessionManager)
{
$configuration = $this->getConnectionConfiguration();
$client = new Client($configuration, $rpcClientManager, $sessionManager);
$allParticipants = new Participants([
1 => new Collection([
new ParticipantShort([
'tid' => 1,
'participant_info' => [
'firstname' => 'John',
'lastname' => 'Scott',
'email' => 'john@scott.com',
],
]),
new ParticipantShort([
'tid' => 2,
'participant_info' => [
'firstname' => 'Mary',
'lastname' => 'Jane',
'email' => 'mary@jane.com',
],
]),
]),
2 => new Collection([
new ParticipantShort(),
]),
]);
$this->serviceWithParticipants = new SurveyService($client, null, $allParticipants);
}
} }

View File

@@ -33,7 +33,7 @@ class MethodTypeTest extends BaseTypeTestCase
*/ */
public function testGetValidatedMethodWithIncorrectMethod($incorrectMethod) public function testGetValidatedMethodWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException(UnknownMethodException::class);
MethodType::getValidatedMethod($incorrectMethod); MethodType::getValidatedMethod($incorrectMethod);
} }
@@ -52,7 +52,7 @@ class MethodTypeTest extends BaseTypeTestCase
*/ */
public function testIsResultIterableWithIncorrectMethod($incorrectMethod) public function testIsResultIterableWithIncorrectMethod($incorrectMethod)
{ {
$this->expectException(UnknownMethodException::class); $this->setExpectedException(UnknownMethodException::class);
MethodType::isResultIterable($incorrectMethod); MethodType::isResultIterable($incorrectMethod);
} }
@@ -176,6 +176,7 @@ class MethodTypeTest extends BaseTypeTestCase
'EXPORT_STATISTICS' => MethodType::EXPORT_STATISTICS, 'EXPORT_STATISTICS' => MethodType::EXPORT_STATISTICS,
'GET_PARTICIPANT_PROPERTIES' => MethodType::GET_PARTICIPANT_PROPERTIES, 'GET_PARTICIPANT_PROPERTIES' => MethodType::GET_PARTICIPANT_PROPERTIES,
'GET_QUESTION_PROPERTIES' => MethodType::GET_QUESTION_PROPERTIES, 'GET_QUESTION_PROPERTIES' => MethodType::GET_QUESTION_PROPERTIES,
'GET_SUMMARY' => MethodType::GET_SUMMARY,
'LIST_PARTICIPANTS' => MethodType::LIST_PARTICIPANTS, 'LIST_PARTICIPANTS' => MethodType::LIST_PARTICIPANTS,
'LIST_QUESTIONS' => MethodType::LIST_QUESTIONS, 'LIST_QUESTIONS' => MethodType::LIST_QUESTIONS,
'LIST_SURVEYS' => MethodType::LIST_SURVEYS, 'LIST_SURVEYS' => MethodType::LIST_SURVEYS,

View File

@@ -30,10 +30,11 @@ class ReasonTypeTest extends BaseTypeTestCase
protected function getAllExpectedTypes() protected function getAllExpectedTypes()
{ {
return [ return [
'NOT_EXISTING_SURVEY_ID' => ReasonType::NOT_EXISTING_SURVEY_ID, 'NOT_EXISTING_SURVEY_ID' => ReasonType::NOT_EXISTING_SURVEY_ID,
'NO_PARTICIPANTS_FOUND' => ReasonType::NO_PARTICIPANTS_FOUND, 'NO_PARTICIPANTS_FOUND' => ReasonType::NO_PARTICIPANTS_FOUND,
'NO_SURVEYS_FOUND' => ReasonType::NO_SURVEYS_FOUND, 'NO_PARTICIPANT_PROPERTIES' => ReasonType::NO_PARTICIPANT_PROPERTIES,
'NO_TOKEN_TABLE' => ReasonType::NO_TOKEN_TABLE, 'NO_SURVEYS_FOUND' => ReasonType::NO_SURVEYS_FOUND,
'NO_TOKEN_TABLE' => ReasonType::NO_TOKEN_TABLE,
]; ];
} }

View File

@@ -0,0 +1,38 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\LimeSurvey\Test\ApiClient\Utilities;
use DateTime;
/**
* Date-related utility
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DateUtility
{
/**
* Returns date formatted with long or medium format
*
* @param bool $useLongFormat (optional) If is set to true, long format will be used (default behaviour).
* Otherwise - medium format.
* @return string
*/
public static function getDateTime($useLongFormat = true)
{
$format = 'Y-m-d H:i';
if ($useLongFormat) {
$format = 'Y-m-d H:i:s';
}
return (new DateTime())->format($format);
}
}