Skip to content
Snippets Groups Projects
Commit c0b7693f authored by Pieter Frenssen's avatar Pieter Frenssen
Browse files

Issue #3365120 by pfrenssen: LogicException: Missing type Integer

parent d5199e2c
No related branches found
No related tags found
1 merge request!3Issue #3365120: LogicException: Missing type Integer
......@@ -17,7 +17,7 @@ use GraphQL\Type\Definition\ResolveInfo;
* nullable = true,
* multi = false,
* arguments = {
* "depth" = "Integer",
* "depth" = "Int",
* },
* )
*/
......
......@@ -14,7 +14,7 @@ use GraphQL\Type\Definition\ResolveInfo;
* parents = {"WebformElementValidationMultiple"},
* id = "webform_element_validation_limit",
* name = "limit",
* type = "Integer",
* type = "Int",
* )
*/
class WebformElementValidationLimit extends FieldPluginBase {
......
......@@ -15,7 +15,7 @@ use GraphQL\Type\Definition\ResolveInfo;
* parents = {"WebformFileUploadOutput"},
* id = "webform_file_upload_fid",
* name = "fid",
* type = "Integer",
* type = "Int",
* )
*/
class WebformFileUploadOutputFid extends FieldPluginBase {
......
......@@ -47,7 +47,8 @@ elements: |-
'#help': 'Help text'
'#file_placeholder': Placeholder
'#max_filesize': '2'
'#file_extensions': 'gif jpg png'
'#file_extensions': 'gif jpg png txt'
'#uri_scheme': public
radios:
'#type': radios
'#title': Radios
......@@ -62,6 +63,13 @@ elements: |-
'#options':
1: 'Option 1'
2: 'Option 2'
term_select:
'#type': webform_term_select
'#title': 'Term select'
'#multiple': 2
'#description': 'Select one or two tags.'
'#vocabulary': tags
'#depth': 1
actions:
'#type': webform_actions
'#title': 'Submit button(s)'
......
mutation createFile($file: Upload!, $webform_id: String!, $webform_element_id: String!){
webformFileUpload(file: $file, webform_id: $webform_id, webform_element_id: $webform_element_id) {
... on WebformFileUploadOutput {
fid
}
}
}
fragment webformElementTermSelect on WebformElementTermSelect {
__typename
id
title
description
multiple {
limit
}
termOptions(depth: $depth) {
name
}
}
query webform($webform_id: String!, $depth: Int!) {
form: webformById(webform_id: $webform_id) {
title
elements {
...webformElementTermSelect
}
}
}
......@@ -22,7 +22,7 @@ class ActionsTest extends GraphQLWebformKernelTestBase {
'form' => [
'title' => 'GraphQL Webform test form',
'elements' => [
9 => [
10 => [
'__typename' => 'WebformElementActions',
'submitLabel' => 'Set sail for adventure',
],
......
<?php
declare(strict_types = 1);
namespace Drupal\Tests\graphql_webform\Kernel\Element;
use Drupal\Core\File\FileSystemInterface;
use Drupal\file\FileInterface;
use Drupal\file\FileStorageInterface;
use Drupal\Tests\graphql_webform\Kernel\GraphQLWebformKernelTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests uploading a file for a webform.
*
* @group graphql_webform
*/
class CreateFileTest extends GraphQLWebformKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'file',
];
/**
* The file storage.
*
* @var \Drupal\file\FileStorageInterface|null
*/
protected ?FileStorageInterface $fileStorage;
/**
* The file system.
*
* @var \Drupal\Core\File\FileSystemInterface|null
*/
protected ?FileSystemInterface $fileSystem;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('file');
$this->fileStorage = $this->container->get('entity_type.manager')->getStorage('file');
$this->fileSystem = $this->container->get('file_system');
}
/**
* Tests uploading a file through the webformFileUpload mutation.
*/
public function testFileUpload() {
// This is failing because of a bug in GraphQL.
// @see https://github.com/drupal-graphql/graphql/issues/982
$this->markTestSkipped('Re-enable once issue #982 is fixed.');
// We are pretending to upload a file into temporary storage. Ensure a file
// is there because the Symfony UploadedFile component will check that.
$file = $this->fileSystem->getTempDirectory() . '/graphql_webform_upload_test.txt';
touch($file);
// Create a post request with file contents.
$request = Request::create('/graphql', 'POST', [
'query' => $this->getQueryFromFile('create_file.gql'),
// The variable has to be declared null.
'variables' => [
'file' => NULL,
'webform_element_id' => 'file_upload',
'webform_id' => 'graphql_webform_test_form',
],
// Then map the file upload name to the variable.
'map' => [
'test' => ['variables.file'],
],
], [], [
'test' => [
'name' => 'test.txt',
'type' => 'text/plain',
'size' => 42,
'tmp_name' => $file,
'error' => UPLOAD_ERR_OK,
],
]);
$request->headers->add(['content-type' => 'multipart/form-data']);
$response = $this->container->get('http_kernel')->handle($request);
$result = json_decode($response->getContent());
// Check that the file ID was returned.
$returned_fid = $result->data->webformFileUpload->fid ?? NULL;
$this->assertIsInt($returned_fid);
// Check that the file entity was created.
$file = $this->fileStorage->load($returned_fid);
$this->assertInstanceOf(FileInterface::class, $file);
$this->assertEquals('test.txt', $file->getFilename());
$this->assertEquals('text/plain', $file->getMimeType());
}
}
namespace Drupal\graphql_webform\Plugin\GraphQL\Mutations;
/**
* Mock the PHP function is_uploaded_file().
*
* Since we are not *really* uploading a file through the webserver, PHP will
* not recognize the file as an uploaded file. We mock the function to return
* TRUE for our test file.
*
* @param string $filename
* The filename being checked.
*
* @return bool
* Will return TRUE for our test file.
*/
function is_uploaded_file($filename) {
$temp_dir = \Drupal::service('file_system')->getTempDirectory();
$test_file = $temp_dir . '/graphql_webform_upload_test.txt';
return $filename === $test_file;
}
namespace Drupal\Core\File;
/**
* Mock the PHP function move_uploaded_file().
*
* Since we are not *really* uploading a file through the webserver, PHP will
* refuse to move the file and will return FALSE. We mock the function to return
* TRUE for our test file.
*
* @param string $filename
* The filename being moved.
* @param string $destination
* The destination path.
*
* @return bool
* Will return TRUE for our test file.
*/
function move_uploaded_file($filename, $destination) {
$temp_dir = \Drupal::service('file_system')->getTempDirectory();
$test_file = $temp_dir . '/graphql_webform_upload_test.txt';
return $filename === $test_file;
}
......@@ -17,7 +17,6 @@ class ManagedFileTest extends GraphQLWebformKernelTestBase {
* Tests managed files.
*/
public function testManagedFile(): void {
$this->markTestSkipped();
$query = $this->getQueryFromFile('managed_file.gql');
$this->assertResults($query, ['webform_id' => 'graphql_webform_test_form'], [
'form' => [
......@@ -29,7 +28,7 @@ class ManagedFileTest extends GraphQLWebformKernelTestBase {
'title' => 'File upload',
'description' => 'Description',
'maxFilesize' => '2',
'fileExtensions' => 'gif jpg png',
'fileExtensions' => 'gif jpg png txt',
'multiple' => [
'limit' => '0',
],
......
<?php
declare(strict_types = 1);
namespace Drupal\Tests\graphql_webform\Kernel\Element;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Language\LanguageInterface;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\TermInterface;
use Drupal\taxonomy\VocabularyInterface;
use Drupal\Tests\graphql_webform\Kernel\GraphQLWebformKernelTestBase;
/**
* Tests for the WebformElementTermSelect type.
*
* @group graphql_webform
*/
class TermSelectTest extends GraphQLWebformKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'graphql_core',
'path_alias',
'taxonomy',
'text',
];
/**
* A test vocabulary.
*
* @var \Drupal\taxonomy\VocabularyInterface|null
*/
protected ?VocabularyInterface $vocabulary;
/**
* Test terms, keyed by name.
*
* @var \Drupal\taxonomy\TermInterface[]
*/
protected array $terms = [];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Set up the Taxonomy module.
$this->installEntitySchema('taxonomy_term');
$this->installEntitySchema('taxonomy_vocabulary');
$this->installEntitySchema('user');
$this->installConfig(['taxonomy']);
// Create the 'Tags' vocabulary which is used in the test webform.
$this->vocabulary = Vocabulary::create([
'vid' => 'tags',
]);
$this->vocabulary->save();
// Create a hierarchy of test terms.
$terms = ['A' => ['B1', 'B2']];
foreach ($terms as $parent => $children) {
$this->terms[$parent] = $this->createTerm($parent);
foreach ($children as $child) {
$this->terms[$child] = $this->createTerm($child, $this->terms[$parent]);
}
}
}
/**
* Tests the term select element with different depths.
*
* @dataProvider termSelectDepthProvider
*/
public function testTermSelect(int $depth, array $expected_terms): void {
$query = $this->getQueryFromFile('term_select.gql');
$expected_term_options = array_map(fn (string $term_name): array => ['name' => $term_name], $expected_terms);
$this->assertResults($query, [
'webform_id' => 'graphql_webform_test_form',
'depth' => $depth,
], [
'form' => [
'title' => 'GraphQL Webform test form',
'elements' => [
9 => [
'__typename' => 'WebformElementTermSelect',
'id' => 'term_select',
'title' => 'Term select',
'description' => 'Select one or two tags.',
'multiple' => ['limit' => 2],
'termOptions' => $expected_term_options,
],
],
],
], $this->defaultCacheMetaData($expected_terms));
}
/**
* Data provider for testTermSelect().
*
* @return array[]
* An array of test cases. Each test case an array with 2 elements:
* - The depth of terms to select.
* - The expected terms that should be returned.
*/
public function termSelectDepthProvider(): array {
return [
[1, ['A']],
[2, ['A', 'B1', 'B2']],
];
}
/**
* {@inheritdoc}
*/
protected function defaultCacheMetaData(array $expected_terms = []) {
$metadata = new CacheableMetadata();
$metadata->setCacheMaxAge($this->defaultCacheMaxAge());
$metadata->setCacheTags($this->defaultCacheTags($expected_terms));
$metadata->setCacheContexts($this->defaultCacheContexts());
return $metadata;
}
/**
* {@inheritdoc}
*/
protected function defaultCacheTags(array $expected_terms = []): array {
// We expect the cache tags to include the test terms.
return array_merge(
array_map(fn (string $term): string => 'taxonomy_term:' . $this->terms[$term]->id(), $expected_terms),
parent::defaultCacheTags()
);
}
/**
* Creates a test taxonomy term.
*
* @param string $name
* The name of the term.
* @param \Drupal\taxonomy\TermInterface|null $parent
* Optional parent term.
*
* @return \Drupal\taxonomy\TermInterface
* The created term.
*/
protected function createTerm(string $name, ?TermInterface $parent = NULL): TermInterface {
$term = Term::create([
'name' => $name,
'vid' => 'tags',
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
'parent' => $parent,
]);
$term->save();
return $term;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment