├── .gitignore
├── changelog.md
├── composer.json
├── license.md
├── phpunit.xml
├── readme.md
├── src
├── Cache.php
├── Exceptions
│ ├── InvalidArgumentException.php
│ └── UnauthorizedRequestMethodException.php
├── Flarum.php
├── Fluent.php
├── Models
│ ├── Discussion.php
│ └── Model.php
├── Resource
│ ├── Collection.php
│ ├── Item.php
│ └── Resource.php
├── Response
│ └── Factory.php
└── Traits
│ ├── HasRelationships.php
│ └── UsesCache.php
└── tests
├── TestCase.php
└── Unit
└── DiscussionTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | vendor/
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog flagrow/flarum-php-client
2 |
3 | ### 0.2.0-beta.2
4 |
5 | - Allowing easier retrieval on resource items.
6 | - Fixed issue with keys on relationships.
7 |
8 | ### 0.2.0-beta.1
9 |
10 | - Completely rewritten.
11 | - Implemented Fluent building of REST queries.
12 |
13 | ### 0.1.2
14 |
15 | - generic patch method
16 | - patch method for changing user group added (issue #7)
17 |
18 | ### 0.1.1
19 |
20 | - made the client more generic, added a load and create method that can handle any type
21 |
22 | ### 0.1.0
23 |
24 | - basic guzzle implementation
25 | - load discussion without authorization
26 | - create tag with authorization (to assist in an issue asked on Gitter by @rodenastyle)
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flagrow/flarum-api-client",
3 | "description": "Standalone package for calling the API of a Flarum installation.",
4 | "keywords": ["api", "flarum", "flagrow"],
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Daniël Klabbers",
9 | "email": "daniel+flarum@klabbers.email",
10 | "homepage": "http://hyn.io"
11 | }
12 | ],
13 | "support": {
14 | "issues": "https://github.com/flagrow/flarum-api-client/issues",
15 | "source": "https://github.com/flagrow/flarum-api-client"
16 | },
17 | "require": {
18 | "php": "^7.1",
19 | "guzzlehttp/guzzle": "^6.1.1",
20 | "illuminate/support": "^5.3",
21 | "illuminate/cache": "^5.3"
22 | },
23 | "require-dev": {
24 | "phpunit/phpunit": "^6.0"
25 | },
26 | "extra": {
27 | "branch-alias": {
28 | "dev-master": "0.2.x-dev"
29 | }
30 | },
31 | "autoload": {
32 | "psr-4": {
33 | "Flagrow\\Flarum\\Api\\": "src/"
34 | }
35 | },
36 | "autoload-dev": {
37 | "psr-4": {
38 | "Flagrow\\Flarum\\Api\\Tests\\": "tests"
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Flagrow
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | ./tests/unit/
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # flarum-api-client by  [flagrow](https://discuss.flarum.org/d/1832-flagrow-extension-developer-group)
2 |
3 | [](https://packagist.org/packages/flagrow/flarum-api-client) [](https://gitter.im/flagrow/chat)
4 |
5 | This is a generic PHP API client for use in any project. You can simply include this package as a dependency to your project to use it.
6 |
7 | ### installation
8 |
9 | ```bash
10 | composer require flagrow/flarum-api-client
11 | ```
12 |
13 | ### configuration
14 |
15 | In order to start working with the client you might need a Flarum master key:
16 |
17 | 1. Generate a 40 character random, unguessable string, this is the Token needed for this package.
18 | 2. Manually add it to the `api_keys` table using phpmyadmin/adminer or another solution.
19 |
20 | The master key is required to access non-public discussions and running actions otherwise reserved for
21 | Flarum administrators.
22 |
23 | ### examples
24 |
25 | A basic example:
26 |
27 | ```php
28 | discussions()->request();
38 | // Read a specific discussion.
39 | $discussion = $api->discussions()->id(1)->request();
40 | // Read the first page of users.
41 | $users = $api->users()->request();
42 | ```
43 |
44 | An authorized example:
45 |
46 | ```php
47 | $api = Flarum('http://example.com', ['token' => '; userId=1']);
48 | ```
49 |
50 | > The userId refers to a user that has admin permissions or the user you want to run actions for. Appending the userId setting to the token only works for Master keys.
51 |
52 | ### links
53 |
54 | - [on github](https://github.com/flagrow/flarum-api-client)
55 | - [on packagist](http://packagist.com/packages/flagrow/flarum-api-client)
56 | - [issues](https://github.com/flagrow/flarum-api-client/issues)
57 | - [changelog](https://github.com/flagrow/flarum-api-client/changelog.md)
58 |
59 | > Flagrow is a collaboration of Flarum extension developers to provide quality, maintained extensions.
--------------------------------------------------------------------------------
/src/Cache.php:
--------------------------------------------------------------------------------
1 | store = $store;
37 | }
38 |
39 | /**
40 | * @param string $type
41 | * @return Cache
42 | */
43 | public function setActive(string $type): Cache
44 | {
45 | $this->active = $type;
46 |
47 | return $this;
48 | }
49 |
50 | /**
51 | * @return Store
52 | */
53 | public function getActive(): Store
54 | {
55 | return $this->active;
56 | }
57 |
58 | /**
59 | * @param string|null $store
60 | * @return Store
61 | */
62 | public function getStore(string $store = null): Store
63 | {
64 | $store = $store ?? $this->active;
65 |
66 | if (!array_key_exists($store, $this->stores)) {
67 | $this->stores[$store] = clone $this->store;
68 | }
69 |
70 | return $this->stores[$store];
71 | }
72 |
73 | /**
74 | * @param int $id
75 | * @param Item $item
76 | * @param string|null $type
77 | * @return Cache
78 | */
79 | public function set(int $id, Item $item, string $type = null): Cache
80 | {
81 | $this->getStore($type)->put($id, $item, $this->duration);
82 |
83 | return $this;
84 | }
85 |
86 | /**
87 | * @param int $id
88 | * @param null $default
89 | * @param string|null $type
90 | * @return mixed
91 | */
92 | public function get(int $id, $default = null, string $type = null)
93 | {
94 | $value = $this->getStore($type)->get($id);
95 |
96 | return $value ?: $default;
97 | }
98 |
99 | /**
100 | * @param string|null $type
101 | * @return mixed
102 | */
103 | public function all(string $type = null)
104 | {
105 | return $this->getStore($type)->all();
106 | }
107 | }
--------------------------------------------------------------------------------
/src/Exceptions/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 | rest = new Guzzle([
53 | 'base_uri' => "$host/api/",
54 | 'headers' => $this->requestHeaders($authorization)
55 | ]);
56 |
57 | $this->fluent = new Fluent($this);
58 |
59 | static::$cache = new Cache(new ArrayStore);
60 | }
61 |
62 | public static function getCache(): Cache
63 | {
64 | return self::$cache;
65 | }
66 |
67 | public function request()
68 | {
69 | $method = $this->fluent->getMethod();
70 |
71 | /** @var ResponseInterface $response */
72 | try {
73 | $response = $this->rest->{$method}((string)$this->fluent, $this->getVariablesForMethod());
74 | } finally {
75 | // Reset the fluent builder for a new request.
76 | $this->fluent->reset();
77 | }
78 |
79 | if ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300) {
80 | return Factory::build($response);
81 | }
82 | }
83 |
84 | protected function requestHeaders(array $authorization = [])
85 | {
86 | $headers = [
87 | 'Accept' => 'application/vnd.api+json, application/json',
88 | 'User-Agent' => 'Flagrow Api Client'
89 | ];
90 |
91 | $token = Arr::get($authorization, 'token');
92 |
93 | if ($token) {
94 | $this->authorized = true;
95 | Arr::set($headers, 'Authorization', "Token $token");
96 | }
97 |
98 | return $headers;
99 | }
100 |
101 | function __call($name, $arguments)
102 | {
103 | return call_user_func_array([$this->fluent, $name], $arguments);
104 | }
105 |
106 | protected function getVariablesForMethod(): array
107 | {
108 | $variables = $this->fluent->getVariables();
109 |
110 | if (empty($variables)) {
111 | return [];
112 | }
113 |
114 | switch ($this->fluent->getMethod()) {
115 | case 'get':
116 | return $variables;
117 | break;
118 | default:
119 | return [
120 | 'json' => ['data' => $variables]
121 | ];
122 | }
123 | }
124 |
125 | public function getFluent(): Fluent
126 | {
127 | return $this->fluent;
128 | }
129 |
130 | public function getRest(): Guzzle
131 | {
132 | return $this->rest;
133 | }
134 |
135 | public function setStrict(bool $strict): Flarum
136 | {
137 | $this->strict = $strict;
138 | return $this;
139 | }
140 |
141 | public function isStrict(): bool
142 | {
143 | return $this->strict;
144 | }
145 |
146 | public function isAuthorized(): bool
147 | {
148 | return $this->authorized;
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/Fluent.php:
--------------------------------------------------------------------------------
1 | flarum = $flarum;
86 | }
87 |
88 | public function reset()
89 | {
90 | $this->segments = [];
91 | $this->includes = [];
92 | $this->query = [];
93 | $this->variables = [];
94 | $this->method = 'get';
95 |
96 | return $this;
97 | }
98 |
99 | protected function handleType(string $type, $id): Fluent
100 | {
101 | $this->segments[] = $type;
102 |
103 | if ($id) {
104 | $this->segments[] = $id;
105 | }
106 |
107 | return $this;
108 | }
109 |
110 | public function setPath(string $path): Fluent
111 | {
112 | $this->segments = [$path];
113 |
114 | return $this;
115 | }
116 |
117 | /**
118 | * @param string $method
119 | * @return Fluent
120 | * @throws UnauthorizedRequestMethodException
121 | */
122 | public function setMethod(string $method): Fluent
123 | {
124 | $this->method = strtolower($method);
125 |
126 | if (
127 | $this->flarum->isStrict() &&
128 | !$this->flarum->isAuthorized() &&
129 | in_array($this->method, $this->methodsRequiringAuthorization)) {
130 | throw new UnauthorizedRequestMethodException($this->method);
131 | }
132 |
133 | return $this;
134 | }
135 |
136 | public function setVariables(array $variables = [])
137 | {
138 | if (isset($variables['relationships'])) {
139 | foreach ($variables['relationships'] as $relation => $relationship) {
140 | if (! array_get($relationship, 'data')) {
141 | unset($variables['relationships'][$relation]);
142 | $variables['relationships'][$relation]['data'] = $relationship;
143 | }
144 | }
145 | }
146 |
147 | if (count($variables) === 1 && is_array($variables[0])) {
148 | $this->variables = $variables[0];
149 | } else {
150 | $this->variables = $variables;
151 | }
152 |
153 | return $this;
154 | }
155 |
156 | public function getMethod(): string
157 | {
158 | return $this->method;
159 | }
160 |
161 | public function getVariables(): array
162 | {
163 | return $this->variables;
164 | }
165 |
166 | protected function handlePagination(string $type, $value)
167 | {
168 | $this->query[$type] = $value;
169 |
170 | return $this;
171 | }
172 |
173 | public function id(int $id): Fluent
174 | {
175 | $this->segments[] = $id;
176 |
177 | return $this;
178 | }
179 |
180 | public function include(string $include): Fluent
181 | {
182 | $this->includes[] = $include;
183 |
184 | return $this;
185 | }
186 |
187 | public function offset(int $number): Fluent
188 | {
189 | return $this->handlePagination('page[offset]', $number);
190 | }
191 |
192 | /**
193 | * {@inheritdoc}
194 | */
195 | function __toString()
196 | {
197 | $path = implode('/', $this->segments);
198 |
199 | if ($this->includes || $this->query) {
200 | $path .= '?';
201 | }
202 |
203 | if ($this->includes) {
204 | $path .= sprintf(
205 | 'include=%s&',
206 | implode(',', $this->includes)
207 | );
208 | }
209 |
210 | if ($this->query) {
211 | $path .= http_build_query($this->query);
212 | }
213 |
214 | return $path;
215 | }
216 |
217 | /**
218 | * @param $name
219 | * @param $arguments
220 | * @return Fluent
221 | */
222 | function __call($name, $arguments)
223 | {
224 | if (in_array($name, $this->methods)) {
225 | if (!empty($arguments)) {
226 | $this->setVariables($arguments);
227 | }
228 | return $this->setMethod($name, $arguments);
229 | }
230 |
231 | if (count($arguments) <= 1 && in_array($name, $this->types)) {
232 | return $this->handleType($name, $arguments[0] ?? null);
233 | }
234 |
235 | if (in_array($name, $this->pagination) && count($arguments) === 1) {
236 | return call_user_func_array([$this, 'handlePagination'], array_prepend($arguments, $name));
237 | }
238 |
239 | if (method_exists($this->flarum, $name)) {
240 | return call_user_func_array([$this->flarum, $name], $arguments);
241 | }
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/src/Models/Discussion.php:
--------------------------------------------------------------------------------
1 | id = Arr::pluck($attributes, 'id');
31 | }
32 |
33 | $this->attributes = $attributes;
34 | }
35 |
36 | public static function fromResource(Item $item)
37 | {
38 | $class = sprintf("%s\\%s", __NAMESPACE__, Str::camel(Str::singular($item->type)));
39 |
40 | if (class_exists($class)) {
41 | $response = new $class($item->attributes);
42 |
43 | if ($item->id) {
44 | $response->id = $item->id;
45 | }
46 |
47 | return $response;
48 | }
49 |
50 | throw new InvalidArgumentException("Resource type {$item->type} could not be migrated to Model");
51 | }
52 |
53 | /**
54 | * @param Flarum $dispatcher
55 | */
56 | public static function setDispatcher(Flarum $dispatcher)
57 | {
58 | self::$dispatcher = $dispatcher;
59 | }
60 |
61 | /**
62 | * @return Flarum
63 | */
64 | public static function getDispatcher(): Flarum
65 | {
66 | return self::$dispatcher;
67 | }
68 |
69 | /**
70 | * Resource type.
71 | *
72 | * @return string
73 | */
74 | public function type(): string
75 | {
76 | return Str::plural(Str::lower(
77 | Str::replaceFirst(__NAMESPACE__ . '\\', '', static::class)
78 | ));
79 | }
80 |
81 | /**
82 | * Generated resource item.
83 | *
84 | * @return Item
85 | */
86 | public function item(): Item
87 | {
88 | return new Item([
89 | 'type' => $this->type(),
90 | 'attributes' => $this->attributes
91 | ]);
92 | }
93 |
94 | /**
95 | * @return array
96 | */
97 | public function attributes(): array
98 | {
99 | return $this->attributes;
100 | }
101 |
102 | /**
103 | * @param Model $relation
104 | */
105 | public function addRelation($relation)
106 | {
107 |
108 | }
109 |
110 | /**
111 | * @return Fluent
112 | */
113 | public function baseRequest(): Fluent
114 | {
115 | // Set resource type.
116 | $dispatch = call_user_func_array([
117 | static::$dispatcher,
118 | $this->type()
119 | ], []);
120 |
121 | // Set resource Id.
122 | if ($this->id) {
123 | $dispatch->id($this->id);
124 | }
125 |
126 | return $dispatch;
127 | }
128 |
129 | /**
130 | * @return mixed
131 | */
132 | public function delete()
133 | {
134 | if (!$this->id) {
135 | throw new InvalidArgumentException("Resource doesn't exist.");
136 | }
137 |
138 | return $this->baseRequest()->delete()->request();
139 | }
140 |
141 | /**
142 | * Creates or updates a resource.
143 | *
144 | * @return mixed
145 | */
146 | public function save()
147 | {
148 | return $this->baseRequest()
149 | // Set method and variables.
150 | ->post(
151 | $this->item()->toArray()
152 | )
153 | // Send request.
154 | ->request();
155 | }
156 |
157 | /**
158 | * {@inheritdoc}
159 | */
160 | function __set($name, $value)
161 | {
162 | if ($name === 'id') {
163 | $this->id = $value;
164 | } else {
165 | $this->attributes[$name] = $value;
166 | }
167 | }
168 |
169 | /**
170 | * {@inheritdoc}
171 | */
172 | function __get($name)
173 | {
174 | return Arr::get($this->attributes, $name);
175 | }
176 | }
--------------------------------------------------------------------------------
/src/Resource/Collection.php:
--------------------------------------------------------------------------------
1 | items[$item->id] = $item;
23 | }
24 | }
25 |
26 | /**
27 | * @return Collection
28 | */
29 | public function cache()
30 | {
31 | foreach ($this->items as $id => $item) {
32 | $item->cache();
33 | }
34 |
35 | return $this;
36 | }
37 |
38 | /**
39 | * @return Collect
40 | */
41 | public function collect(): Collect
42 | {
43 | return collect($this->items)->keyBy('id');
44 | }
45 |
46 | /**
47 | * @param string $by
48 | * @param int|null $amount
49 | * @return Collect
50 | */
51 | public function latest(string $by = 'created_at', int $amount = null): Collect
52 | {
53 | $set = $this->collect()->sortBy($by);
54 |
55 | if ($amount) {
56 | $set = $set->splice(0, $amount);
57 | }
58 |
59 | return $set;
60 | }
61 | }
--------------------------------------------------------------------------------
/src/Resource/Item.php:
--------------------------------------------------------------------------------
1 | id = (int) Arr::get($item, 'id');
30 | $this->type = Arr::get($item, 'type');
31 | $this->attributes = Arr::get($item, 'attributes', []);
32 |
33 | $this->relations(Arr::get($item, 'relationships', []));
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | function __get($name)
40 | {
41 | if (Arr::has($this->attributes, $name)) {
42 | return Arr::get($this->attributes, $name);
43 | }
44 |
45 | if (Arr::has($this->relationships, $name)) {
46 | return Arr::get($this->relationships, $name);
47 | }
48 | }
49 |
50 | public function toArray()
51 | {
52 | return [
53 | 'id' => $this->id,
54 | 'type' => $this->type,
55 | 'attributes' => $this->attributes,
56 | 'relationships' => $this->relationships
57 | ];
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Resource/Resource.php:
--------------------------------------------------------------------------------
1 | getStatusCode() === 204) {
15 | return true;
16 | }
17 |
18 | $body = $response->getBody()->getContents();
19 |
20 | if (empty($body)) {
21 | return null;
22 | }
23 |
24 | $json = json_decode($body, true);
25 |
26 | $data = Arr::get($json, 'data');
27 | $included = Arr::get($json, 'included', []);
28 |
29 | // Sets included values to global store.
30 | if (!empty($included)) {
31 | (new Collection($included))->cache();
32 | }
33 |
34 | // Collection, paginated
35 | if ($data && !array_key_exists('type', $data)) {
36 | return (new Collection($data))->cache();
37 | }
38 |
39 | return (new Item($data))->cache();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Traits/HasRelationships.php:
--------------------------------------------------------------------------------
1 | $relation) {
24 | $data = Arr::get($relation, 'data');
25 |
26 | // Single item.
27 | if (Arr::get($data, 'type')) {
28 | $this->relationships[$attribute] = $this->parseRelationshipItem(
29 | Arr::get($data, 'type'),
30 | Arr::get($data, 'id')
31 | );
32 | } else {
33 | $this->relationships[$attribute] = [];
34 |
35 | foreach ($data as $item) {
36 | $id = (int) Arr::get($item, 'id');
37 | $this->relationships[$attribute][$id] = $this->parseRelationshipItem(
38 | Arr::get($item, 'type'),
39 | $id
40 | );
41 | }
42 | }
43 | }
44 | }
45 |
46 | /**
47 | * @param string $type
48 | * @param int $id
49 | * @return Item|null
50 | */
51 | protected function parseRelationshipItem(string $type, int $id)
52 | {
53 | return Flarum::getCache()->get($id, null, $type);
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Traits/UsesCache.php:
--------------------------------------------------------------------------------
1 | set($this->id, $this, $this->type);
16 |
17 | return $this;
18 | }
19 | }
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | flarum = new Flarum(
22 | getenv('FLARUM_HOST') ?? 'https://discuss.flarum.org',
23 | $token ? compact('token') : []
24 | );
25 |
26 | Model::setDispatcher($this->flarum);
27 | }
28 | }
--------------------------------------------------------------------------------
/tests/Unit/DiscussionTest.php:
--------------------------------------------------------------------------------
1 | flarum->discussions()->request();
21 |
22 | $this->assertTrue($collection instanceof Collection);
23 |
24 | $this->assertGreaterThan(0, $collection->collect()->count());
25 |
26 | return $collection;
27 | }
28 |
29 | /**
30 | * @test
31 | * @depends frontpage
32 | * @param Collection $collection
33 | */
34 | public function discussion(Collection $collection)
35 | {
36 | /** @var Item $discussion */
37 | $discussion = $collection->collect()->first();
38 |
39 | /** @var Item $item */
40 | $item = $this->flarum->discussions()->id($discussion->id)->request();
41 |
42 | $this->assertEquals($discussion->id, $item->id, 'Requesting an existing discussion retrieves an incorrect result.');
43 | $this->assertEquals($discussion->type, $item->type, 'Requesting an existing discussion retrieves an incorrect resource type.');
44 |
45 | $cached = Flarum::getCache()->get($discussion->id, null, $discussion->type);
46 |
47 | $this->assertNotNull($cached, 'Discussion was not automatically persisted to global store.');
48 | $this->assertEquals($discussion->id, $cached->id, 'The wrong discussion was stored into cache.');
49 |
50 | $this->assertNotNull($discussion->title);
51 | $this->assertNotNull($discussion->slug);
52 |
53 | $this->assertNotNull($discussion->tags, 'The relation tags should be set on a discussion.');
54 |
55 | $this->assertNotNull($discussion->startPost, 'A discussion has a start post.');
56 | }
57 |
58 | /**
59 | * @test
60 | */
61 | public function createsDiscussions()
62 | {
63 | if (! $this->flarum->isAuthorized()) {
64 | $this->markTestSkipped('No authentication set.');
65 | }
66 |
67 | $discussion = new Discussion([
68 | 'title' => 'Foo',
69 | 'content' => 'Some testing content'
70 | ]);
71 |
72 | $resource = $discussion->save();
73 |
74 | $this->assertInstanceOf(Item::class, $resource);
75 |
76 | $this->assertEquals($discussion->title, $resource->title);
77 | $this->assertNotEmpty($resource->startPost);
78 | $this->assertEquals($discussion->content, $resource->startPost->content);
79 |
80 | return $resource;
81 | }
82 |
83 | /**
84 | * @test
85 | * @depends createsDiscussions
86 | * @param Item $resource
87 | */
88 | public function deletesDiscussions(Item $resource)
89 | {
90 | if (! $this->flarum->isAuthorized()) {
91 | $this->markTestSkipped('No authentication set.');
92 | }
93 |
94 | $discussion = Discussion::fromResource($resource);
95 | $model = Model::fromResource($resource);
96 |
97 | // Resolve the same instance.
98 | $this->assertEquals($discussion, $model);
99 |
100 | // See if we can delete things.
101 | $this->assertTrue($discussion->delete());
102 | }
103 | }
--------------------------------------------------------------------------------