xmosaicsource: add fetch capability (related to #290474)

authorSamuel Trégouët <samuel.tregouet@logilab.fr>
changesete42b0a6715ee
branchdefault
phasepublic
hiddenno
parent revision#6d443c26a058 components: add a new xmosaicsource component (related to #290474)
child revision#a13d46e7ef7b xmosaicsource: move sources management from xmosaicframe to xmosaicsource
files modified by this revision
components/xmosaicsource/xmosaicsource.js
test/src/xmosaicsource.js
# HG changeset patch
# User Samuel Trégouët <samuel.tregouet@logilab.fr>
# Date 1428939287 -7200
# Mon Apr 13 17:34:47 2015 +0200
# Node ID e42b0a6715ee39c1dfcfd394aa6766f791dcc96a
# Parent 6d443c26a058108df1f07f662fc28abb659815c4
xmosaicsource: add fetch capability (related to #290474)

diff --git a/components/xmosaicsource/xmosaicsource.js b/components/xmosaicsource/xmosaicsource.js
@@ -1,15 +1,113 @@
1  (function(ownerDocument) {
2      'use strict';
3      var xSourceProto = Object.create(HTMLElement.prototype);
4 
5 +    function neo4jFetch(baseurl, query) {
6 +        return $.ajax({
7 +            url: baseurl,
8 +            accepts: "application/json; charset=UTF-8",
9 +            dataType: "json",
10 +            data: {
11 +                    "query": query,
12 +                    "params": {}
13 +                },
14 +            type: "POST"
15 +        });
16 +    }
17 +
18 +    function sparqlFetch(baseurl, query) {
19 +        return $.ajax({
20 +            url: baseurl,
21 +            accepts: {
22 +                'json': "application/sparql-results+json"
23 +            },
24 +            data: {
25 +                'query': query,
26 +                'defaul-graph-uri': '',
27 +                'shuod-sponge': '',
28 +                'format': 'application/sparql-results+json',
29 +                'debug': 'on',
30 +                'timeout': 0
31 +            },
32 +            type: "GET"
33 +        });
34 +    }
35 +
36 +    function cwFetch(baseurl, query) {
37 +        return $.ajax({
38 +            url: baseurl,
39 +            accepts: "application/json; charset=UTF-8",
40 +            dataType: "json",
41 +            xhrFields: {
42 +                withCredentials: true
43 +            },
44 +            data: {
45 +                "rql": query,
46 +                "vid": 'ejsonexport'
47 +            },
48 +            type: "GET"
49 +        });
50 +    }
51 +
52 +    function httpFetch(baseurl, query) {
53 +        // join baseurl and query with a `/`
54 +        var queryPath = query.replace(/^\//, ''),
55 +            baseUrl = baseurl.replace(/\/$/, ''),
56 +            url = queryPath ? baseUrl + '/' + queryPath : baseUrl;
57 +        return $.ajax({
58 +            url: url,
59 +            type: "HEAD",
60 +            beforeSend: function(jqxhr, settings) {
61 +                jqxhr.reqUrl = url;
62 +            }
63 +        });
64 +    }
65 +
66 +    xSourceProto.updateQuery = function updateQuery() {
67 +        var fetcher = null, source = this.dataset.source;
68 +        if (source === 'neo4j') {
69 +            fetcher = neo4jFetch;
70 +        } else if (source === 'sparql') {
71 +            fetcher = sparqlFetch;
72 +        } else if (source === 'cw') {
73 +            fetcher = cwFetch;
74 +        } else if (source === 'http') {
75 +            fetcher = httpFetch;
76 +        }
77 +        if (!fetcher) {
78 +            this.dispatchEvent(new CustomEvent('error', {
79 +                detail: {
80 +                    err: new Error('nothing to fetch: ' +
81 +                                   'unknown source "' + source + '"')
82 +                }
83 +            }));
84 +            return;
85 +        }
86 +        fetcher(this.dataset.baseurl, this.dataset.query)
87 +            .done(function(data, status, xhr) {
88 +                this.dispatchEvent(new CustomEvent('load', {
89 +                    detail: {
90 +                        rset: data,
91 +                        xhr: xhr,
92 +                        reqUrl: xhr.reqUrl
93 +                    }
94 +                }));
95 +            }.bind(this))
96 +            .fail(function(xhr, err, msg) {
97 +                this.dispatchEvent(new CustomEvent('error', {
98 +                    detail: {
99 +                        err: err,
100 +                        msg: msg,
101 +                        xhr: xhr
102 +                    }
103 +                }));
104 +            }.bind(this));
105 +    };
106 +
107      xSourceProto.attachedCallback = function attachedCallback() {
108 -        this.dispatchEvent(new CustomEvent('load', {
109 -            detail: {
110 -                ctx: null
111 -            }
112 -        }));
113 +        this.updateQuery();
114      };
115 
116 
117      document.registerElement('x-mosaic-source', {
118          prototype: xSourceProto
diff --git a/test/src/xmosaicsource.js b/test/src/xmosaicsource.js
@@ -4,24 +4,51 @@
119  var expect = require('test/lib/chai').expect;
120 
121 
122  describe('source custom element', function() {
123      var qs = document.querySelector.bind(document);
124 -    var sourceElement;
125 +    var sourceElement, server;
126 
127 
128      beforeEach(function() {
129          sourceElement = document.createElement('x-mosaic-source');
130 +        // setup a fake server which will keep all ajax calls
131 +        server = sinon.fakeServer.create();
132      });
133      afterEach(function() {
134          sourceElement.remove();
135 +        // restore ajax
136 +        server.restore();
137      });
138 
139 -    it('should fire `load` CustomEvent after creation', function(done) {
140 -        sourceElement.addEventListener('load', function(ev) {
141 -            expect(ev.detail).to.have.property('ctx');
142 +    it('should fire `error` CustomEvent after creation', function(done) {
143 +        sourceElement.addEventListener('error', function(ev) {
144 +            expect(ev.detail).to.have.property('err');
145 +            expect(ev.detail.err).to.be.an.instanceOf(Error);
146              done();
147          });
148          document.body.appendChild(sourceElement);
149 
150      });
151 +
152 +    it('should fetch cw source', function(done) {
153 +        sourceElement.addEventListener('load', function(ev) {
154 +            expect(ev.detail).to.have.property('xhr');
155 +            expect(ev.detail).to.have.property('rset');
156 +            expect(ev.detail).to.have.property('reqUrl');
157 +            expect(ev.detail.rset).to.deep.equal([]);
158 +            done();
159 +        });
160 +        document.body.appendChild(sourceElement);
161 +        sourceElement.dataset.baseurl = '/baseurl';
162 +        sourceElement.dataset.query = 'super query';
163 +        sourceElement.dataset.source = 'cw';
164 +        sourceElement.updateQuery();
165 +
166 +        // get first ajax request
167 +        var req = server.requests[0];
168 +        // assert url of this request
169 +        expect(req.url).to.equal('/baseurl?rql=super+query&vid=ejsonexport');
170 +        // respond to this request
171 +        req.respond(200, {'Content-Type': 'application/json'}, '[]');
172 +    });
173  });