Skip to content
File

Blob: src/workerd/api/tests/actor-stub-test.js

javascript125 lines
1// Copyright (c) 2023 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5// We want to test the behavior of the Durable Object stub now that it uses name interception to
6// behave like a JS Proxy object.
7import * as assert from 'node:assert';
8 
9export class DurableObjectExample {
10 constructor() {
11 this.check = true;
12 }
13 
14 async fetch(request) {
15 return new Response('OK');
16 }
17 
18 async foo() {
19 // Server side impl of foo.
20 return 'foo from remote';
21 }
22 
23 async throw() {
24 throw 1;
25 }
26 
27 thisCheck() {
28 if (this.check !== true) {
29 throw new Error('incorrect this within rpc function call');
30 }
31 return true;
32 }
33}
34 
35async function checkDurableObject(obj) {
36 assert.equal(await obj.foo(), 'foo from remote');
37 assert.equal(await obj.thisCheck(), true);
38 assert.deepStrictEqual(await obj.fetch('http://foo/'), new Response('OK'));
39 assert.rejects(obj.throw());
40}
41 
42function checkNullishJurisdiction(env, jurisdiction) {
43 const id1 = env.ns.jurisdiction(jurisdiction).newUniqueId();
44 const stub1 = env.ns.get(id1);
45 checkDurableObject(stub1);
46 const id2 = env.ns.newUniqueId({ jurisdiction });
47 const stub2 = env.ns.get(id2);
48 checkDurableObject(stub2);
49}
50 
51export default {
52 async test(_request, env, _ctx) {
53 // This test verifies we can still use registered methods like `fetch()`, and also confirms that
54 // dynamic names (foo() in this case) can also be called.
55 //
56 // We should still be able to define names on the stub in JS and get the expected result.
57 
58 // Check properties of DurableObjectId.
59 const id = env.ns.idFromName('foo');
60 assert.equal(id.name, 'foo');
61 assert.equal(id.jurisdiction, undefined);
62 
63 {
64 // Check that no two DurableObjectId created via `newUniqueId()` are equal.
65 const id1 = env.ns.newUniqueId();
66 const id2 = env.ns.newUniqueId();
67 assert.equal(!id1.equals(id2), true);
68 }
69 
70 // Check round tripping of DurableObjectId to string.
71 //
72 // Note: `name` property is dropped from `env.ns.idFromString(id.toString())`
73 assert.equal(env.ns.idFromString(id.toString()).toString(), id.toString());
74 
75 // Check properties of DurableObject.
76 let obj = env.ns.get(id);
77 assert.equal(Object.keys(obj).length, 2);
78 assert.equal(obj.name, 'foo');
79 assert.equal(obj.id, id);
80 assert.equal(obj.id.name, 'foo');
81 assert.equal(obj.id.jurisdiction, undefined);
82 
83 // Check that we can call methods on a DurableObject.
84 checkDurableObject(obj);
85 
86 {
87 // Check that DurableObject constructed with `locationHint` is equivalent to `obj`.
88 let otherObj = env.ns.get(id, { locationHint: 'wnam' });
89 assert.deepStrictEqual(obj, otherObj);
90 checkDurableObject(otherObj);
91 }
92 
93 {
94 // Check that DurableObject constructed via `getByName()` is equivalent to `obj`.
95 let otherObj = env.ns.getByName('foo');
96 assert.deepStrictEqual(obj, otherObj);
97 checkDurableObject(otherObj);
98 }
99 
100 {
101 // Check that DurableObject constructed with `locationHint` and `getByName()` is equivalent
102 // to `obj`.
103 let otherObj = env.ns.getByName('foo', { locationHint: 'wnam' });
104 assert.deepStrictEqual(obj, otherObj);
105 checkDurableObject(otherObj);
106 }
107 
108 {
109 // Check that nullish jurisdictions work in Workerd
110 checkNullishJurisdiction(env, null);
111 checkNullishJurisdiction(env, undefined);
112 }
113 
114 // Check that methods can be defined on DurableObject and are callable.
115 obj.baz = () => {
116 return 'called baz';
117 };
118 assert.equal(Object.keys(obj).length, 3);
119 assert.equal(typeof obj.baz, 'function');
120 assert.equal(obj.baz(), 'called baz');
121 
122 return new Response('OK');
123 },
124};