Completed
Push — master ( 247d13...46aee1 )
by Zac
13:30 queued 12s
created

TestApiController   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 3 Features 0
Metric Value
wmc 15
c 6
b 3
f 0
lcom 1
cbo 8
dl 0
loc 203
ccs 49
cts 49
cp 1
rs 10

7 Methods

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