selectionset_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package interpreter
  11. import (
  12. "encoding/json"
  13. "testing"
  14. )
  15. func TestSortingAndLimiting(t *testing.T) {
  16. gm, _ := songGraphGroups()
  17. query := map[string]interface{}{
  18. "operationName": nil,
  19. "query": `
  20. {
  21. Song(ascending:"key") {
  22. key
  23. name
  24. }
  25. }
  26. `,
  27. "variables": nil,
  28. }
  29. if rerr := checkResult(`
  30. {
  31. "data": {
  32. "Song": [
  33. {
  34. "key": "Aria1",
  35. "name": "Aria1"
  36. },
  37. {
  38. "key": "Aria2",
  39. "name": "Aria2"
  40. },
  41. {
  42. "key": "Aria3",
  43. "name": "Aria3"
  44. },
  45. {
  46. "key": "Aria4",
  47. "name": "Aria4"
  48. },
  49. {
  50. "key": "DeadSong2",
  51. "name": "DeadSong2"
  52. },
  53. {
  54. "key": "FightSong4",
  55. "name": "FightSong4"
  56. },
  57. {
  58. "key": "LoveSong3",
  59. "name": "LoveSong3"
  60. },
  61. {
  62. "key": "MyOnlySong3",
  63. "name": "MyOnlySong3"
  64. },
  65. {
  66. "key": "StrangeSong1",
  67. "name": "StrangeSong1"
  68. }
  69. ]
  70. }
  71. }`[1:], query, gm); rerr != nil {
  72. t.Error(rerr)
  73. return
  74. }
  75. query = map[string]interface{}{
  76. "operationName": nil,
  77. "query": `
  78. {
  79. Song(ascending:"name", last: 3) {
  80. key
  81. name
  82. }
  83. }
  84. `,
  85. "variables": nil,
  86. }
  87. if rerr := checkResult(`
  88. {
  89. "data": {
  90. "Song": [
  91. {
  92. "key": "LoveSong3",
  93. "name": "LoveSong3"
  94. },
  95. {
  96. "key": "MyOnlySong3",
  97. "name": "MyOnlySong3"
  98. },
  99. {
  100. "key": "StrangeSong1",
  101. "name": "StrangeSong1"
  102. }
  103. ]
  104. }
  105. }`[1:], query, gm); rerr != nil {
  106. t.Error(rerr)
  107. return
  108. }
  109. query = map[string]interface{}{
  110. "operationName": nil,
  111. "query": `
  112. {
  113. Song(descending:"name", last: 3) {
  114. key
  115. name
  116. }
  117. }
  118. `,
  119. "variables": nil,
  120. }
  121. if rerr := checkResult(`
  122. {
  123. "data": {
  124. "Song": [
  125. {
  126. "key": "Aria3",
  127. "name": "Aria3"
  128. },
  129. {
  130. "key": "Aria2",
  131. "name": "Aria2"
  132. },
  133. {
  134. "key": "Aria1",
  135. "name": "Aria1"
  136. }
  137. ]
  138. }
  139. }`[1:], query, gm); rerr != nil {
  140. t.Error(rerr)
  141. return
  142. }
  143. query = map[string]interface{}{
  144. "operationName": nil,
  145. "query": `
  146. {
  147. Song(ascending:"ranking", last: 3) {
  148. key
  149. name
  150. ranking
  151. }
  152. }
  153. `,
  154. "variables": nil,
  155. }
  156. if rerr := checkResult(`
  157. {
  158. "data": {
  159. "Song": [
  160. {
  161. "key": "Aria1",
  162. "name": "Aria1",
  163. "ranking": 8
  164. },
  165. {
  166. "key": "Aria4",
  167. "name": "Aria4",
  168. "ranking": 18
  169. },
  170. {
  171. "key": "MyOnlySong3",
  172. "name": "MyOnlySong3",
  173. "ranking": 19
  174. }
  175. ]
  176. }
  177. }`[1:], query, gm); rerr != nil {
  178. t.Error(rerr)
  179. return
  180. }
  181. query = map[string]interface{}{
  182. "operationName": nil,
  183. "query": `
  184. {
  185. Song(descending:"ranking", last: 3) {
  186. key
  187. name
  188. ranking
  189. }
  190. }
  191. `,
  192. "variables": nil,
  193. }
  194. if rerr := checkResult(`
  195. {
  196. "data": {
  197. "Song": [
  198. {
  199. "key": "FightSong4",
  200. "name": "FightSong4",
  201. "ranking": 3
  202. },
  203. {
  204. "key": "Aria2",
  205. "name": "Aria2",
  206. "ranking": 2
  207. },
  208. {
  209. "key": "LoveSong3",
  210. "name": "LoveSong3",
  211. "ranking": 1
  212. }
  213. ]
  214. }
  215. }`[1:], query, gm); rerr != nil {
  216. t.Error(rerr)
  217. return
  218. }
  219. query = map[string]interface{}{
  220. "operationName": nil,
  221. "query": `
  222. {
  223. Song(ascending:"name", items: 2, last: 3) {
  224. key
  225. name
  226. }
  227. }
  228. `,
  229. "variables": nil,
  230. }
  231. if rerr := checkResult(`
  232. {
  233. "data": {
  234. "Song": [
  235. {
  236. "key": "LoveSong3",
  237. "name": "LoveSong3"
  238. },
  239. {
  240. "key": "MyOnlySong3",
  241. "name": "MyOnlySong3"
  242. }
  243. ]
  244. }
  245. }`[1:], query, gm); rerr != nil {
  246. t.Error(rerr)
  247. return
  248. }
  249. // From the last 3 we retrieve item 1 and the next
  250. query = map[string]interface{}{
  251. "operationName": nil,
  252. "query": `
  253. {
  254. Song(ascending:"name", from : 1, items: 2, last: 3) {
  255. key
  256. name
  257. }
  258. }
  259. `,
  260. "variables": nil,
  261. }
  262. if rerr := checkResult(`
  263. {
  264. "data": {
  265. "Song": [
  266. {
  267. "key": "MyOnlySong3",
  268. "name": "MyOnlySong3"
  269. },
  270. {
  271. "key": "StrangeSong1",
  272. "name": "StrangeSong1"
  273. }
  274. ]
  275. }
  276. }`[1:], query, gm); rerr != nil {
  277. t.Error(rerr)
  278. return
  279. }
  280. query = map[string]interface{}{
  281. "operationName": nil,
  282. "query": `
  283. {
  284. Song(ascending:"name", from : 100, items: 200, last: 2) {
  285. key
  286. name
  287. }
  288. }
  289. `,
  290. "variables": nil,
  291. }
  292. if rerr := checkResult(`
  293. {
  294. "data": {
  295. "Song": [
  296. {
  297. "key": "MyOnlySong3",
  298. "name": "MyOnlySong3"
  299. },
  300. {
  301. "key": "StrangeSong1",
  302. "name": "StrangeSong1"
  303. }
  304. ]
  305. }
  306. }`[1:], query, gm); rerr != nil {
  307. t.Error(rerr)
  308. return
  309. }
  310. query = map[string]interface{}{
  311. "operationName": nil,
  312. "query": `
  313. {
  314. Song(ascending:"name", descending:"key") {
  315. key
  316. name
  317. }
  318. }
  319. `,
  320. "variables": nil,
  321. }
  322. if rerr := checkResult(`
  323. {
  324. "data": {
  325. "Song": []
  326. },
  327. "errors": [
  328. {
  329. "locations": [
  330. {
  331. "column": 45,
  332. "line": 3
  333. }
  334. ],
  335. "message": "Cannot specify ascending and descending sorting",
  336. "path": [
  337. "Song"
  338. ]
  339. }
  340. ]
  341. }`[1:], query, gm); rerr != nil {
  342. t.Error(rerr)
  343. return
  344. }
  345. query = map[string]interface{}{
  346. "operationName": nil,
  347. "query": `
  348. {
  349. Song(ascending:"hans") {
  350. key
  351. name
  352. }
  353. }
  354. `,
  355. "variables": nil,
  356. }
  357. if rerr := checkResult(`
  358. {
  359. "data": {
  360. "Song": [
  361. {
  362. "key": "StrangeSong1",
  363. "name": "StrangeSong1"
  364. },
  365. {
  366. "key": "FightSong4",
  367. "name": "FightSong4"
  368. },
  369. {
  370. "key": "DeadSong2",
  371. "name": "DeadSong2"
  372. },
  373. {
  374. "key": "LoveSong3",
  375. "name": "LoveSong3"
  376. },
  377. {
  378. "key": "MyOnlySong3",
  379. "name": "MyOnlySong3"
  380. },
  381. {
  382. "key": "Aria1",
  383. "name": "Aria1"
  384. },
  385. {
  386. "key": "Aria2",
  387. "name": "Aria2"
  388. },
  389. {
  390. "key": "Aria3",
  391. "name": "Aria3"
  392. },
  393. {
  394. "key": "Aria4",
  395. "name": "Aria4"
  396. }
  397. ]
  398. }
  399. }`[1:], query, gm); rerr != nil {
  400. t.Error(rerr)
  401. return
  402. }
  403. }
  404. func TestFragments(t *testing.T) {
  405. gm, _ := songGraphGroups()
  406. // Test fragments for different return types
  407. query := map[string]interface{}{
  408. "operationName": nil,
  409. "query": `
  410. {
  411. Song(key : "StrangeSong1") {
  412. song_key : key
  413. foo : bar(traverse : ":::") {
  414. key
  415. kind
  416. ...groupFields
  417. ...authorFields @skip(if: false)
  418. }
  419. }
  420. }
  421. fragment groupFields on group {
  422. owner
  423. }
  424. fragment authorFields on Author {
  425. name
  426. }
  427. `,
  428. "variables": nil,
  429. }
  430. if rerr := checkResult(`
  431. {
  432. "data": {
  433. "Song": [
  434. {
  435. "foo": [
  436. {
  437. "key": "123",
  438. "kind": "Author",
  439. "name": "Mike"
  440. },
  441. {
  442. "key": "Best",
  443. "kind": "group",
  444. "owner": "noowner"
  445. }
  446. ],
  447. "song_key": "StrangeSong1"
  448. }
  449. ]
  450. }
  451. }`[1:], query, gm); rerr != nil {
  452. t.Error(rerr)
  453. return
  454. }
  455. // Test fragments for different return types - now using inline fragments
  456. query = map[string]interface{}{
  457. "operationName": nil,
  458. "query": `
  459. {
  460. Song(key : "StrangeSong1") {
  461. song_key : key
  462. foo : bar(traverse : ":::") {
  463. key
  464. kind
  465. ... on group @skip(if: false) {
  466. owner
  467. }
  468. ... on Author {
  469. name
  470. }
  471. }
  472. }
  473. }
  474. `,
  475. "variables": nil,
  476. }
  477. if rerr := checkResult(`
  478. {
  479. "data": {
  480. "Song": [
  481. {
  482. "foo": [
  483. {
  484. "key": "123",
  485. "kind": "Author",
  486. "name": "Mike"
  487. },
  488. {
  489. "key": "Best",
  490. "kind": "group",
  491. "owner": "noowner"
  492. }
  493. ],
  494. "song_key": "StrangeSong1"
  495. }
  496. ]
  497. }
  498. }`[1:], query, gm); rerr != nil {
  499. t.Error(rerr)
  500. return
  501. }
  502. query = map[string]interface{}{
  503. "operationName": nil,
  504. "query": `
  505. {
  506. key
  507. name1 : name
  508. ...SongKind
  509. ...foo
  510. }
  511. fragment SongKind on Song {
  512. kind
  513. name2 : name
  514. key
  515. }
  516. `,
  517. "variables": nil,
  518. }
  519. if rerr := checkResult("", query, gm); rerr == nil ||
  520. rerr.Error() != "Fatal GraphQL query error in test: Invalid construct (Fragment foo is not defined) (Line:2 Pos:2)" {
  521. t.Error(rerr)
  522. return
  523. }
  524. query = map[string]interface{}{
  525. "operationName": nil,
  526. "query": `
  527. {
  528. key
  529. name1 : name
  530. ...SongKind
  531. ...foo
  532. }
  533. fragment SongKind on Song {
  534. kind
  535. name2 : name
  536. key
  537. }
  538. fragment SongKind on Song {
  539. kind
  540. name2 : name
  541. key
  542. }
  543. `,
  544. "variables": nil,
  545. }
  546. if rerr := checkResult("", query, gm); rerr == nil ||
  547. rerr.Error() != "Fatal GraphQL query error in test: Ambiguous definition (Fragment SongKind defined multiple times) (Line:2 Pos:2)" {
  548. t.Error(rerr)
  549. return
  550. }
  551. }
  552. func TestMutation(t *testing.T) {
  553. gm, _ := songGraphGroups()
  554. query := map[string]interface{}{
  555. "operationName": nil,
  556. "query": `
  557. {
  558. Song(storeNode : {
  559. key:"newsongkey",
  560. name:"newsongname"
  561. }, key : "newsongkey") {
  562. key,
  563. name
  564. }
  565. }
  566. `,
  567. "variables": nil,
  568. }
  569. if rerr := checkResult(`
  570. {
  571. "data": {
  572. "Song": []
  573. },
  574. "errors": [
  575. {
  576. "locations": [
  577. {
  578. "column": 25,
  579. "line": 6
  580. }
  581. ],
  582. "message": "Operation must be a mutation to modify data",
  583. "path": [
  584. "Song"
  585. ]
  586. }
  587. ]
  588. }`[1:], query, gm); rerr != nil {
  589. t.Error(rerr)
  590. return
  591. }
  592. query = map[string]interface{}{
  593. "operationName": nil,
  594. "query": `
  595. mutation {
  596. Song(storeNode : {
  597. key : "newsongkey",
  598. name : "newsongname"
  599. }, storeEdge : {
  600. key : "newedgekey",
  601. kind : "newedgekind"
  602. end1key : "newsongkey",
  603. end1kind : "Song",
  604. end1role : "song",
  605. end1cascading : false,
  606. end2key : "Best",
  607. end2kind : "group",
  608. end2role : "group",
  609. end2cascading : false,
  610. },key : "newsongkey") {
  611. key,
  612. name,
  613. group(traverse : ":::group") {
  614. key
  615. otherMembers(traverse : ":::Song", matches : {
  616. not_key : "newsongkey",
  617. name : "^.*Song[0-9]$"
  618. }) {
  619. key,
  620. kind,
  621. name,
  622. }
  623. }
  624. }
  625. }
  626. `,
  627. "variables": nil,
  628. }
  629. result, _ := runQuery("test", "main", query, gm, nil, true)
  630. actualResultBytes, _ := json.MarshalIndent(result, "", " ")
  631. actualResult := string(actualResultBytes)
  632. if actualResult != `{
  633. "data": {
  634. "Song": []
  635. },
  636. "errors": [
  637. {
  638. "locations": [
  639. {
  640. "column": 26,
  641. "line": 17
  642. }
  643. ],
  644. "message": "Can only perform read operations",
  645. "path": [
  646. "Song"
  647. ]
  648. }
  649. ]
  650. }` {
  651. t.Error("Unexpected result:", actualResult)
  652. return
  653. }
  654. if rerr := checkResult(`
  655. {
  656. "data": {
  657. "Song": [
  658. {
  659. "group": [
  660. {
  661. "key": "Best",
  662. "otherMembers": [
  663. {
  664. "key": "LoveSong3",
  665. "kind": "Song",
  666. "name": "LoveSong3"
  667. },
  668. {
  669. "key": "MyOnlySong3",
  670. "kind": "Song",
  671. "name": "MyOnlySong3"
  672. },
  673. {
  674. "key": "StrangeSong1",
  675. "kind": "Song",
  676. "name": "StrangeSong1"
  677. }
  678. ]
  679. }
  680. ],
  681. "key": "newsongkey",
  682. "name": "newsongname"
  683. }
  684. ]
  685. }
  686. }`[1:], query, gm); rerr != nil {
  687. t.Error(rerr)
  688. return
  689. }
  690. query = map[string]interface{}{
  691. "operationName": nil,
  692. "query": `
  693. mutation {
  694. Song(removeNode : {
  695. key : "newsongkey",
  696. }, removeEdge : {
  697. key : "newedgekey",
  698. kind : "newedgekind"
  699. },key : "newsongkey") {
  700. key,
  701. name,
  702. group(traverse : ":::group") {
  703. key
  704. otherMembers(traverse : ":::Song", matches : {
  705. not_key : "newsongkey",
  706. name : "^.*Song[0-9]$"
  707. }) {
  708. key,
  709. kind,
  710. name,
  711. }
  712. }
  713. }
  714. }
  715. `,
  716. "variables": nil,
  717. }
  718. if rerr := checkResult(`
  719. {
  720. "data": {
  721. "Song": []
  722. }
  723. }`[1:], query, gm); rerr != nil {
  724. t.Error(rerr)
  725. return
  726. }
  727. query = map[string]interface{}{
  728. "operationName": nil,
  729. "query": `
  730. mutation {
  731. Song(removeNode : {}) {
  732. key
  733. kind
  734. }
  735. }
  736. `,
  737. "variables": nil,
  738. }
  739. if rerr := checkResult(`
  740. {
  741. "data": {
  742. "Song": []
  743. }
  744. }`[1:], query, gm); rerr != nil {
  745. t.Error(rerr)
  746. return
  747. }
  748. query = map[string]interface{}{
  749. "operationName": nil,
  750. "query": `
  751. mutation {
  752. Song(storeNode : "Hans", storeEdge : "Franz", key : "Honk") {
  753. key,
  754. name,
  755. }
  756. }`,
  757. "variables": nil,
  758. }
  759. if rerr := checkResult(`{
  760. "data": {
  761. "Song": []
  762. },
  763. "errors": [
  764. {
  765. "locations": [
  766. {
  767. "column": 64,
  768. "line": 3
  769. }
  770. ],
  771. "message": "Object required for node attributes and values",
  772. "path": [
  773. "Song"
  774. ]
  775. },
  776. {
  777. "locations": [
  778. {
  779. "column": 64,
  780. "line": 3
  781. }
  782. ],
  783. "message": "Object required for edge attributes and values",
  784. "path": [
  785. "Song"
  786. ]
  787. }
  788. ]
  789. }`, query, gm); rerr != nil {
  790. t.Error(rerr)
  791. return
  792. }
  793. query = map[string]interface{}{
  794. "operationName": nil,
  795. "query": `
  796. mutation {
  797. Song(removeNode : "Hans", removeEdge : "Franz", key : "Honk") {
  798. key,
  799. name,
  800. }
  801. }`,
  802. "variables": nil,
  803. }
  804. if rerr := checkResult(`{
  805. "data": {
  806. "Song": []
  807. },
  808. "errors": [
  809. {
  810. "locations": [
  811. {
  812. "column": 66,
  813. "line": 3
  814. }
  815. ],
  816. "message": "Object required for node key and kind",
  817. "path": [
  818. "Song"
  819. ]
  820. },
  821. {
  822. "locations": [
  823. {
  824. "column": 66,
  825. "line": 3
  826. }
  827. ],
  828. "message": "Object required for edge key and kind",
  829. "path": [
  830. "Song"
  831. ]
  832. }
  833. ]
  834. }`, query, gm); rerr != nil {
  835. t.Error(rerr)
  836. return
  837. }
  838. }
  839. func TestTraversals(t *testing.T) {
  840. gm, _ := songGraphGroups()
  841. query := map[string]interface{}{
  842. "operationName": nil,
  843. "query": `
  844. {
  845. Song(key : "StrangeSong1") {
  846. song_key : key
  847. foo : bar(traverse : ":::") {
  848. key
  849. kind
  850. Name : name
  851. }
  852. }
  853. }
  854. `,
  855. "variables": nil,
  856. }
  857. if rerr := checkResult(`
  858. {
  859. "data": {
  860. "Song": [
  861. {
  862. "foo": [
  863. {
  864. "Name": "Mike",
  865. "key": "123",
  866. "kind": "Author"
  867. },
  868. {
  869. "Name": null,
  870. "key": "Best",
  871. "kind": "group"
  872. }
  873. ],
  874. "song_key": "StrangeSong1"
  875. }
  876. ]
  877. }
  878. }`[1:], query, gm); rerr != nil {
  879. t.Error(rerr)
  880. return
  881. }
  882. }
  883. func TestListQueries(t *testing.T) {
  884. gm, _ := songGraphGroups()
  885. query := map[string]interface{}{
  886. "operationName": "foo",
  887. "query": `
  888. {
  889. Song {
  890. key
  891. }
  892. }
  893. `,
  894. "variables": nil,
  895. }
  896. _, err := runQuery("test", "main", query, gm, nil, false)
  897. if err == nil || err.Error() != "Fatal GraphQL operation error in test: Missing operation (Operation foo not found) (Line:2 Pos:2)" {
  898. t.Error("Unexpected result:", err)
  899. return
  900. }
  901. query = map[string]interface{}{
  902. "operationName": nil,
  903. "query": `
  904. fragment friendFields on User {
  905. id
  906. name
  907. profilePic(size: 50)
  908. }
  909. `,
  910. "variables": nil,
  911. }
  912. res, err := runQuery("test", "main", query, gm, nil, false)
  913. if err == nil || err.Error() != "Fatal GraphQL operation error in test: Missing operation (No executable expression found) (Line:2 Pos:2)" {
  914. t.Error("Unexpected result:", res, err)
  915. return
  916. }
  917. query = map[string]interface{}{
  918. "operationName": nil,
  919. "query": `
  920. {
  921. Song1 : Song {
  922. song_key : key
  923. song_key1 : key
  924. song_key1 : name # This is illegal and will be ignored
  925. song_key1 : key
  926. name
  927. name
  928. }
  929. group {
  930. key
  931. },
  932. }
  933. `,
  934. "variables": nil,
  935. }
  936. if rerr := checkResult(`
  937. {
  938. "data": {
  939. "Song1": [
  940. {
  941. "name": "StrangeSong1",
  942. "song_key": "StrangeSong1",
  943. "song_key1": "StrangeSong1"
  944. },
  945. {
  946. "name": "FightSong4",
  947. "song_key": "FightSong4",
  948. "song_key1": "FightSong4"
  949. },
  950. {
  951. "name": "DeadSong2",
  952. "song_key": "DeadSong2",
  953. "song_key1": "DeadSong2"
  954. },
  955. {
  956. "name": "LoveSong3",
  957. "song_key": "LoveSong3",
  958. "song_key1": "LoveSong3"
  959. },
  960. {
  961. "name": "MyOnlySong3",
  962. "song_key": "MyOnlySong3",
  963. "song_key1": "MyOnlySong3"
  964. },
  965. {
  966. "name": "Aria1",
  967. "song_key": "Aria1",
  968. "song_key1": "Aria1"
  969. },
  970. {
  971. "name": "Aria2",
  972. "song_key": "Aria2",
  973. "song_key1": "Aria2"
  974. },
  975. {
  976. "name": "Aria3",
  977. "song_key": "Aria3",
  978. "song_key1": "Aria3"
  979. },
  980. {
  981. "name": "Aria4",
  982. "song_key": "Aria4",
  983. "song_key1": "Aria4"
  984. }
  985. ],
  986. "group": [
  987. {
  988. "key": "Best"
  989. }
  990. ]
  991. },
  992. "errors": [
  993. {
  994. "locations": [
  995. {
  996. "column": 17,
  997. "line": 3
  998. }
  999. ],
  1000. "message": "Field identifier song_key1 used multiple times",
  1001. "path": [
  1002. "Song1"
  1003. ]
  1004. },
  1005. {
  1006. "locations": [
  1007. {
  1008. "column": 17,
  1009. "line": 3
  1010. }
  1011. ],
  1012. "message": "Field identifier name used multiple times",
  1013. "path": [
  1014. "Song1"
  1015. ]
  1016. }
  1017. ]
  1018. }`[1:], query, gm); rerr != nil {
  1019. t.Error(rerr)
  1020. return
  1021. }
  1022. query = map[string]interface{}{
  1023. "operationName": nil,
  1024. "query": `
  1025. {
  1026. Song(key : "StrangeSong1") {
  1027. song_key : key
  1028. name
  1029. }
  1030. }
  1031. `,
  1032. "variables": nil,
  1033. }
  1034. if rerr := checkResult(`
  1035. {
  1036. "data": {
  1037. "Song": [
  1038. {
  1039. "name": "StrangeSong1",
  1040. "song_key": "StrangeSong1"
  1041. }
  1042. ]
  1043. }
  1044. }`[1:], query, gm); rerr != nil {
  1045. t.Error(rerr)
  1046. return
  1047. }
  1048. query = map[string]interface{}{
  1049. "operationName": nil,
  1050. "query": `
  1051. {
  1052. Song(matches : { name : "Aria[2-4]", not_name : "Aria4", foo : "a[" }) {
  1053. song_key : key
  1054. }
  1055. }
  1056. `,
  1057. "variables": nil,
  1058. }
  1059. if rerr := checkResult(`
  1060. {
  1061. "data": {
  1062. "Song": [
  1063. {
  1064. "song_key": "Aria2"
  1065. },
  1066. {
  1067. "song_key": "Aria3"
  1068. }
  1069. ]
  1070. },
  1071. "errors": [
  1072. {
  1073. "locations": [
  1074. {
  1075. "column": 79,
  1076. "line": 3
  1077. }
  1078. ],
  1079. "message": "Regex a[ did not compile: error parsing regexp: missing closing ]: `[1:]+"`[`"+`",
  1080. "path": [
  1081. "Song"
  1082. ]
  1083. }
  1084. ]
  1085. }`, query, gm); rerr != nil {
  1086. t.Error(rerr)
  1087. return
  1088. }
  1089. query = map[string]interface{}{
  1090. "operationName": nil,
  1091. "query": `
  1092. {
  1093. Song(matches : { name1 : "test" }) {
  1094. song_key : key
  1095. }
  1096. }
  1097. `,
  1098. "variables": nil,
  1099. }
  1100. if rerr := checkResult(`{
  1101. "data": {
  1102. "Song": []
  1103. }
  1104. }`, query, gm); rerr != nil {
  1105. t.Error(rerr)
  1106. return
  1107. }
  1108. query = map[string]interface{}{
  1109. "operationName": nil,
  1110. "query": `
  1111. {
  1112. Song(matches : [ "name1", "test" ]) {
  1113. }
  1114. }
  1115. `,
  1116. "variables": nil,
  1117. }
  1118. if rerr := checkResult(`{
  1119. "data": {
  1120. "Song": [
  1121. {},
  1122. {},
  1123. {},
  1124. {},
  1125. {},
  1126. {},
  1127. {},
  1128. {},
  1129. {}
  1130. ]
  1131. },
  1132. "errors": [
  1133. {
  1134. "locations": [
  1135. {
  1136. "column": 45,
  1137. "line": 3
  1138. }
  1139. ],
  1140. "message": "Matches expression is not a map",
  1141. "path": [
  1142. "Song"
  1143. ]
  1144. }
  1145. ]
  1146. }`, query, gm); rerr != nil {
  1147. t.Error(rerr)
  1148. return
  1149. }
  1150. query = map[string]interface{}{
  1151. "operationName": nil,
  1152. "query": `
  1153. fragment Song on Song {
  1154. key
  1155. name1 : name
  1156. ...SongKind
  1157. }
  1158. query b { # This should be executed
  1159. Song {
  1160. key
  1161. ...Song
  1162. }
  1163. }
  1164. query a {
  1165. Song1 {
  1166. key1
  1167. }
  1168. }
  1169. fragment SongKind on Song {
  1170. kind
  1171. name2 : name
  1172. key
  1173. }
  1174. `,
  1175. "variables": nil,
  1176. }
  1177. if rerr := checkResult(`
  1178. {
  1179. "data": {
  1180. "Song": [
  1181. {
  1182. "key": "StrangeSong1",
  1183. "kind": "Song",
  1184. "name1": "StrangeSong1",
  1185. "name2": "StrangeSong1"
  1186. },
  1187. {
  1188. "key": "FightSong4",
  1189. "kind": "Song",
  1190. "name1": "FightSong4",
  1191. "name2": "FightSong4"
  1192. },
  1193. {
  1194. "key": "DeadSong2",
  1195. "kind": "Song",
  1196. "name1": "DeadSong2",
  1197. "name2": "DeadSong2"
  1198. },
  1199. {
  1200. "key": "LoveSong3",
  1201. "kind": "Song",
  1202. "name1": "LoveSong3",
  1203. "name2": "LoveSong3"
  1204. },
  1205. {
  1206. "key": "MyOnlySong3",
  1207. "kind": "Song",
  1208. "name1": "MyOnlySong3",
  1209. "name2": "MyOnlySong3"
  1210. },
  1211. {
  1212. "key": "Aria1",
  1213. "kind": "Song",
  1214. "name1": "Aria1",
  1215. "name2": "Aria1"
  1216. },
  1217. {
  1218. "key": "Aria2",
  1219. "kind": "Song",
  1220. "name1": "Aria2",
  1221. "name2": "Aria2"
  1222. },
  1223. {
  1224. "key": "Aria3",
  1225. "kind": "Song",
  1226. "name1": "Aria3",
  1227. "name2": "Aria3"
  1228. },
  1229. {
  1230. "key": "Aria4",
  1231. "kind": "Song",
  1232. "name1": "Aria4",
  1233. "name2": "Aria4"
  1234. }
  1235. ]
  1236. },
  1237. "errors": [
  1238. {
  1239. "locations": [
  1240. {
  1241. "column": 9,
  1242. "line": 8
  1243. }
  1244. ],
  1245. "message": "Field identifier key used multiple times",
  1246. "path": [
  1247. "Song"
  1248. ]
  1249. }
  1250. ]
  1251. }`[1:], query, gm); rerr != nil {
  1252. t.Error(rerr)
  1253. return
  1254. }
  1255. }
  1256. func TestShortcutListQueries(t *testing.T) {
  1257. gm, _ := songGraphGroups()
  1258. query := map[string]interface{}{
  1259. "operationName": nil,
  1260. "query": `
  1261. {
  1262. Song(matches : {name : ["Aria1", Aria2, "Aria3" ]}) {
  1263. foo : key
  1264. name
  1265. bar: Author {
  1266. name
  1267. }
  1268. }
  1269. }
  1270. `,
  1271. "variables": nil,
  1272. }
  1273. if rerr := checkResult(`
  1274. {
  1275. "data": {
  1276. "Song": [
  1277. {
  1278. "bar": [
  1279. {
  1280. "name": "John"
  1281. }
  1282. ],
  1283. "foo": "Aria1",
  1284. "name": "Aria1"
  1285. },
  1286. {
  1287. "bar": [
  1288. {
  1289. "name": "John"
  1290. }
  1291. ],
  1292. "foo": "Aria2",
  1293. "name": "Aria2"
  1294. },
  1295. {
  1296. "bar": [
  1297. {
  1298. "name": "John"
  1299. }
  1300. ],
  1301. "foo": "Aria3",
  1302. "name": "Aria3"
  1303. }
  1304. ]
  1305. }
  1306. }`[1:], query, gm); rerr != nil {
  1307. t.Error(rerr)
  1308. return
  1309. }
  1310. }