Failed Conditions
Pull Request — master (#142)
by Zac
03:56
created

TestApiController::getTestAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 0
cts 4
cp 0
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 6
1
<?php
2
3
namespace Overwatch\TestBundle\Controller;
4
5
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
6
use Overwatch\ExpectationBundle\Exception\ExpectationNotFoundException;
7
use Overwatch\TestBundle\Entity\Test;
8
use Overwatch\TestBundle\Entity\TestGroup;
9
use Overwatch\TestBundle\Security\TestGroupVoter;
10
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
13
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
use Symfony\Component\HttpFoundation\JsonResponse;
16
use Symfony\Component\HttpFoundation\Request;
17
18
/**
19
 * ApiController
20
 * Handles API requests made for Tests
21
 * 
22
 * @Route("/api/tests")
23
 */
24
class TestApiController extends Controller
0 ignored issues
show
Coding Style introduced by
The property $_em is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
25
{
26
    private $_em;
27
    private $expectationManager;
28
    
29
    public function setContainer(ContainerInterface $container = null)
30
    {
31
        parent::setContainer($container);
32
        $this->_em = $this->getDoctrine()->getManager();
33
        $this->expectationManager = $this->get('overwatch_expectation.expectation_manager');
34
    }
35
36
    /**
37
     * Returns the details of the given test
38
     * 
39
     * @Route("/{id}")
40
     * @Method({"GET"})
41
     * @ApiDoc(
42
     *     resource=true,
43
     *     requirements={
44
     *         {"name"="id", "description"="The ID of the test to return", "dataType"="integer", "requirement"="\d+"}
45
     *     },
46
     *     tags={
47
     *         "Super Admin" = "#ff1919",
48
     *         "Admin" = "#ffff33",
49
     *         "User" = "#75ff47"
50
     *     }
51
     * )
52
     */
53
    public function getTestAction(Test $test)
54
    {
55
        if (!$this->isGranted(TestGroupVoter::VIEW, $test->getGroup())) {
56
            throw $this->createAccessDeniedException('You must be a member of this test\'s group to view it');
57
        }
58
        
59
        return new JsonResponse($test);
60
    }
61
    
62
    /**
63
     * Creates a test in the given group
64
     * 
65
     * @Route("/group/{id}")
66
     * @Method({"POST"})
67
     * @Security("is_granted('edit', group)")
68
     * @ApiDoc(
69
     *     resource=true,
70
     *     parameters={
71
     *         {"name"="name", "description"="A user-friendly name for the test", "required"=true, "format"="Github Status", "dataType"="string"},
72
     *         {"name"="actual", "description"="The actual value to test against", "required"=true, "format"="status.github.com", "dataType"="string"},
73
     *         {"name"="expectation", "description"="The expectation to test with", "required"=true, "format"="toResolveTo", "dataType"="string"},
74
     *         {"name"="expected", "description"="The expected value to test against", "required"=false, "format"="octostatus-production.github.com", "dataType"="string"},
75
     *     },
76
     *     requirements={
77
     *         {"name"="id", "description"="The ID of the group to create the test under", "dataType"="integer", "requirement"="\d+"}
78
     *     },
79
     *     tags={
80
     *         "Super Admin" = "#ff1919",
81
     *         "Admin" = "#ffff33"
82
     *     }
83
     * )
84
     */
85
    public function createTestAction(Request $request, TestGroup $group)
86
    {
87
        $test = new Test();
88
        $test
89
            ->setActual($request->request->get('actual'))
90
            ->setExpectation($request->request->get('expectation'))
91
            ->setExpected($request->request->get('expected'))
92
            ->setName($request->request->get('name'))
93
            ->setGroup($group)
94
        ;
95
        
96
        try {
97
            $this->expectationManager->get($test->getExpectation());
98
        } catch (ExpectationNotFoundException $ex) {
99
            return new JsonResponse("Expectation '" . $test->getExpectation() . "' could not be found", JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
100
        }
101
        
102
        if ($test->getActual() === null) {
103
            return new JsonResponse('An actual value to test against must be provided.', JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
104
        }
105
        
106
        $this->_em->persist($test);
107
        $this->_em->flush();
108
        
109
        return new JsonResponse($test, JsonResponse::HTTP_CREATED);
110
    }
111
    
112
    /**
113
     * Returns a list of tests in the given group
114
     * 
115
     * @Route("/group/{id}")
116
     * @Method({"GET"})
117
     * @Security("is_granted('view', group)")
118
     * @ApiDoc(
119
     *     requirements={
120
     *         {"name"="id", "description"="The ID of the group to return tests from", "dataType"="integer", "requirement"="\d+"}
121
     *     },
122
     *     tags={
123
     *         "Super Admin" = "#ff1919",
124
     *         "Admin" = "#ffff33",
125
     *         "User" = "#75ff47"
126
     *     }
127
     * )
128
     */
129
    public function getTestsInGroupAction(TestGroup $group)
130
    {
131
        return new JsonResponse($group->getTests()->toArray());
132
    }
133
    
134
    /**
135
     * Updates the details of the given test
136
     * 
137
     * @Route("/{id}")
138
     * @Method({"PUT"})
139
     * @ApiDoc(
140
     *     parameters={
141
     *         {"name"="name", "description"="A user-friendly name for the test", "required"=false, "format"="Github Status", "dataType"="string"},
142
     *         {"name"="actual", "description"="The actual value to test against", "required"=false, "format"="status.github.com", "dataType"="string"},
143
     *         {"name"="expectation", "description"="The expectation to test with", "required"=false, "format"="toResolveTo", "dataType"="string"},
144
     *         {"name"="expected", "description"="The expected value to test against", "required"=false, "format"="octostatus-production.github.com", "dataType"="string"},
145
     *     },
146
     *     requirements={
147
     *         {"name"="id", "description"="The ID of the test to edit the details of", "dataType"="integer", "requirement"="\d+"}
148
     *     },
149
     *     tags={
150
     *         "Super Admin" = "#ff1919",
151
     *         "Admin" = "#ffff33"
152
     *     }
153
     * )
154
     */
155
    public function updateTestAction(Request $request, Test $test)
156
    {
157
        if (!$this->isGranted(TestGroupVoter::EDIT, $test->getGroup())) {
158
            throw $this->createAccessDeniedException('You must be an admin in this test\'s group to edit it');
159
        }
160
        
161
        foreach (['name', 'actual', 'expectation', 'expected'] as $field) {
162
            if ($request->request->has($field)) {
163
                $test->{'set' . ucfirst($field)}($request->request->get($field));
164
            }
165
        }
166
        
167
        $this->_em->flush();
168
        return new JsonResponse($test);
169
    }
170
    
171
    /**
172
     * Deletes the given test
173
     * 
174
     * @Route("/{id}")
175
     * @Method({"DELETE"})
176
     * @ApiDoc(
177
     *     requirements={
178
     *         {"name"="id", "description"="The ID of the test to delete", "dataType"="integer", "requirement"="\d+"}
179
     *     },
180
     *     tags={
181
     *         "Super Admin" = "#ff1919",
182
     *         "Admin" = "#ffff33"
183
     *     }
184
     * )
185
     */
186
    public function deleteTestAction(Test $test)
187
    {
188
        if (!$this->isGranted(TestGroupVoter::EDIT, $test->getGroup())) {
189
            throw $this->createAccessDeniedException('You must be an admin in this test\'s group to delete it');
190
        }
191
        
192
        $this->_em->remove($test);
193
        $this->_em->flush();
194
        
195
        return new JsonResponse(null, JsonResponse::HTTP_NO_CONTENT);
196
    }
197
    
198
    /**
199
     * Runs a test
200
     * 
201
     * @Route("/{id}")
202
     * @Method({"POST"})
203
     * @ApiDoc(
204
     *     requirements={
205
     *         {"name"="id", "description"="The ID of the test to run", "dataType"="integer", "requirement"="\d+"}
206
     *     },
207
     *     tags={
208
     *         "Super Admin" = "#ff1919",
209
     *         "Admin" = "#ffff33"
210
     *     }
211
     * )
212
     */
213
    public function runTestAction(Test $test)
214
    {
215
        if (!$this->isGranted(TestGroupVoter::EDIT, $test->getGroup())) {
216
            throw $this->createAccessDeniedException('You must be an admin in this test\'s group to run it');
217
        }
218
        
219
        $result = $this->expectationManager->run($test);
220
        
221
        $this->_em->persist($result);
222
        $this->_em->flush();
223
        
224
        return new JsonResponse($result, JsonResponse::HTTP_CREATED);
225
    }
226
}
227