Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.77% covered (success)
96.77%
30 / 31
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryNextSuggestedTaskType
96.77% covered (success)
96.77%
30 / 31
75.00% covered (warning)
75.00%
3 / 4
7
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
3
 mustBePosted
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isInternal
n/a
0 / 0
n/a
0 / 0
1
 getAllowedParams
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace GrowthExperiments\Api;
4
5use ApiQuery;
6use ApiQueryBase;
7use GrowthExperiments\LevelingUp\LevelingUpManager;
8use GrowthExperiments\NewcomerTasks\ConfigurationLoader\ConfigurationLoader;
9use GrowthExperiments\UserImpact\UserImpactLookup;
10use Wikimedia\ParamValidator\ParamValidator;
11
12/**
13 * API module for interacting with the LevelingUpManager, for suggesting new task types to eligible
14 * users. {@see LevelingUpManager}
15 */
16class ApiQueryNextSuggestedTaskType extends ApiQueryBase {
17
18    private LevelingUpManager $levelingUpManager;
19    private ConfigurationLoader $configurationLoader;
20    private UserImpactLookup $userImpactLookup;
21
22    /**
23     * @param ApiQuery $queryModule
24     * @param string $moduleName
25     * @param ConfigurationLoader $configurationLoader
26     * @param LevelingUpManager $levelingUpManager
27     * @param UserImpactLookup $userImpactLookup
28     */
29    public function __construct(
30        ApiQuery $queryModule,
31        $moduleName,
32        ConfigurationLoader $configurationLoader,
33        LevelingUpManager $levelingUpManager,
34        UserImpactLookup $userImpactLookup
35    ) {
36        parent::__construct( $queryModule, $moduleName, 'gnstt' );
37        $this->levelingUpManager = $levelingUpManager;
38        $this->configurationLoader = $configurationLoader;
39        $this->userImpactLookup = $userImpactLookup;
40    }
41
42    /**
43     * @inheritDoc
44     */
45    public function execute() {
46        if ( !$this->getUser()->isNamed() ) {
47            $this->dieWithError( 'apierror-mustbeloggedin-generic' );
48        }
49        $params = $this->extractRequestParams();
50        $this->getResult()->addValue(
51            'query',
52            $this->getModuleName(),
53            $this->levelingUpManager->suggestNewTaskTypeForUser(
54                $this->getUser(),
55                $params['activetasktype'],
56                true
57            )
58        );
59        $userImpact = $this->userImpactLookup->getUserImpact( $this->getUser() );
60        // User impact should definitely exist, but it's typed to potentially return null, so check to be sure.
61        if ( $userImpact ) {
62            // For instrumentation, export the edit count by task type data to the client-side.
63            // We can also use this to implement the "only show every Nth edit" rule when the
64            // user makes multiple edits to an article without reloading the page.
65            // This should logically be in a separate API module, but doesn't seem worth the boilerplate
66            // until there is a use case separate from the "try next task type" workflow.
67            $this->getResult()->addValue(
68                'query',
69                'editcountbytasktype',
70                $userImpact->getEditCountByTaskType()
71            );
72        }
73    }
74
75    /** @inheritDoc */
76    public function mustBePosted() {
77        return true;
78    }
79
80    /**
81     * @inheritDoc
82     * @codeCoverageIgnore
83     */
84    public function isInternal() {
85        return true;
86    }
87
88    /**
89     * @inheritDoc
90     */
91    public function getAllowedParams() {
92        $taskTypes = $this->configurationLoader->getTaskTypes();
93        return [
94            'activetasktype' => [
95                ParamValidator::PARAM_TYPE => array_keys( $taskTypes ),
96                ParamValidator::PARAM_REQUIRED => true,
97            ]
98        ];
99    }
100}