@serenity-js/rest 3.0.0-rc.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +80 -1859
  2. package/README.md +8 -10
  3. package/lib/index.d.ts +2 -1
  4. package/lib/index.d.ts.map +1 -0
  5. package/lib/index.js +6 -2
  6. package/lib/index.js.map +1 -1
  7. package/lib/models/DeleteRequest.d.ts +66 -0
  8. package/lib/models/DeleteRequest.d.ts.map +1 -0
  9. package/lib/models/DeleteRequest.js +73 -0
  10. package/lib/models/DeleteRequest.js.map +1 -0
  11. package/lib/models/GetRequest.d.ts +73 -0
  12. package/lib/models/GetRequest.d.ts.map +1 -0
  13. package/lib/models/GetRequest.js +80 -0
  14. package/lib/models/GetRequest.js.map +1 -0
  15. package/lib/models/HTTPRequest.d.ts +48 -0
  16. package/lib/models/HTTPRequest.d.ts.map +1 -0
  17. package/lib/{model → models}/HTTPRequest.js +14 -23
  18. package/lib/models/HTTPRequest.js.map +1 -0
  19. package/lib/models/HeadRequest.d.ts +58 -0
  20. package/lib/models/HeadRequest.d.ts.map +1 -0
  21. package/lib/models/HeadRequest.js +65 -0
  22. package/lib/models/HeadRequest.js.map +1 -0
  23. package/lib/models/OptionsRequest.d.ts +61 -0
  24. package/lib/models/OptionsRequest.d.ts.map +1 -0
  25. package/lib/models/OptionsRequest.js +68 -0
  26. package/lib/models/OptionsRequest.js.map +1 -0
  27. package/lib/models/PatchRequest.d.ts +65 -0
  28. package/lib/models/PatchRequest.d.ts.map +1 -0
  29. package/lib/models/PatchRequest.js +74 -0
  30. package/lib/models/PatchRequest.js.map +1 -0
  31. package/lib/models/PostRequest.d.ts +105 -0
  32. package/lib/models/PostRequest.d.ts.map +1 -0
  33. package/lib/models/PostRequest.js +114 -0
  34. package/lib/models/PostRequest.js.map +1 -0
  35. package/lib/models/PutRequest.d.ts +75 -0
  36. package/lib/models/PutRequest.d.ts.map +1 -0
  37. package/lib/models/PutRequest.js +84 -0
  38. package/lib/models/PutRequest.js.map +1 -0
  39. package/lib/{model → models}/index.d.ts +1 -0
  40. package/lib/models/index.d.ts.map +1 -0
  41. package/lib/{model → models}/index.js +5 -1
  42. package/lib/models/index.js.map +1 -0
  43. package/lib/screenplay/abilities/CallAnApi.d.ts +88 -99
  44. package/lib/screenplay/abilities/CallAnApi.d.ts.map +1 -0
  45. package/lib/screenplay/abilities/CallAnApi.js +94 -107
  46. package/lib/screenplay/abilities/CallAnApi.js.map +1 -1
  47. package/lib/screenplay/abilities/index.d.ts +1 -0
  48. package/lib/screenplay/abilities/index.d.ts.map +1 -0
  49. package/lib/screenplay/abilities/index.js +5 -1
  50. package/lib/screenplay/abilities/index.js.map +1 -1
  51. package/lib/screenplay/index.d.ts +1 -0
  52. package/lib/screenplay/index.d.ts.map +1 -0
  53. package/lib/screenplay/index.js +5 -1
  54. package/lib/screenplay/index.js.map +1 -1
  55. package/lib/screenplay/interactions/ChangeApiConfig.d.ts +96 -95
  56. package/lib/screenplay/interactions/ChangeApiConfig.d.ts.map +1 -0
  57. package/lib/screenplay/interactions/ChangeApiConfig.js +98 -107
  58. package/lib/screenplay/interactions/ChangeApiConfig.js.map +1 -1
  59. package/lib/screenplay/interactions/Send.d.ts +24 -41
  60. package/lib/screenplay/interactions/Send.d.ts.map +1 -0
  61. package/lib/screenplay/interactions/Send.js +37 -51
  62. package/lib/screenplay/interactions/Send.js.map +1 -1
  63. package/lib/screenplay/interactions/index.d.ts +1 -1
  64. package/lib/screenplay/interactions/index.d.ts.map +1 -0
  65. package/lib/screenplay/interactions/index.js +5 -2
  66. package/lib/screenplay/interactions/index.js.map +1 -1
  67. package/lib/screenplay/questions/LastResponse.d.ts +152 -98
  68. package/lib/screenplay/questions/LastResponse.d.ts.map +1 -0
  69. package/lib/screenplay/questions/LastResponse.js +149 -97
  70. package/lib/screenplay/questions/LastResponse.js.map +1 -1
  71. package/lib/screenplay/questions/index.d.ts +1 -0
  72. package/lib/screenplay/questions/index.d.ts.map +1 -0
  73. package/lib/screenplay/questions/index.js +5 -1
  74. package/lib/screenplay/questions/index.js.map +1 -1
  75. package/package.json +20 -43
  76. package/src/index.ts +1 -1
  77. package/src/models/DeleteRequest.ts +73 -0
  78. package/src/models/GetRequest.ts +80 -0
  79. package/src/{model → models}/HTTPRequest.ts +17 -26
  80. package/src/models/HeadRequest.ts +65 -0
  81. package/src/models/OptionsRequest.ts +68 -0
  82. package/src/models/PatchRequest.ts +75 -0
  83. package/src/models/PostRequest.ts +115 -0
  84. package/src/models/PutRequest.ts +85 -0
  85. package/src/screenplay/abilities/CallAnApi.ts +90 -108
  86. package/src/screenplay/interactions/ChangeApiConfig.ts +99 -111
  87. package/src/screenplay/interactions/Send.ts +46 -61
  88. package/src/screenplay/interactions/index.ts +0 -1
  89. package/src/screenplay/questions/LastResponse.ts +153 -100
  90. package/tsconfig.build.json +10 -0
  91. package/lib/model/DeleteRequest.d.ts +0 -63
  92. package/lib/model/DeleteRequest.js +0 -70
  93. package/lib/model/DeleteRequest.js.map +0 -1
  94. package/lib/model/GetRequest.d.ts +0 -70
  95. package/lib/model/GetRequest.js +0 -77
  96. package/lib/model/GetRequest.js.map +0 -1
  97. package/lib/model/HTTPRequest.d.ts +0 -56
  98. package/lib/model/HTTPRequest.js.map +0 -1
  99. package/lib/model/HeadRequest.d.ts +0 -55
  100. package/lib/model/HeadRequest.js +0 -62
  101. package/lib/model/HeadRequest.js.map +0 -1
  102. package/lib/model/OptionsRequest.d.ts +0 -58
  103. package/lib/model/OptionsRequest.js +0 -65
  104. package/lib/model/OptionsRequest.js.map +0 -1
  105. package/lib/model/PatchRequest.d.ts +0 -65
  106. package/lib/model/PatchRequest.js +0 -74
  107. package/lib/model/PatchRequest.js.map +0 -1
  108. package/lib/model/PostRequest.d.ts +0 -102
  109. package/lib/model/PostRequest.js +0 -111
  110. package/lib/model/PostRequest.js.map +0 -1
  111. package/lib/model/PutRequest.d.ts +0 -75
  112. package/lib/model/PutRequest.js +0 -84
  113. package/lib/model/PutRequest.js.map +0 -1
  114. package/lib/model/index.js.map +0 -1
  115. package/lib/screenplay/interactions/ChangeApiUrl.d.ts +0 -82
  116. package/lib/screenplay/interactions/ChangeApiUrl.js +0 -97
  117. package/lib/screenplay/interactions/ChangeApiUrl.js.map +0 -1
  118. package/src/model/DeleteRequest.ts +0 -71
  119. package/src/model/GetRequest.ts +0 -78
  120. package/src/model/HeadRequest.ts +0 -63
  121. package/src/model/OptionsRequest.ts +0 -66
  122. package/src/model/PatchRequest.ts +0 -76
  123. package/src/model/PostRequest.ts +0 -113
  124. package/src/model/PutRequest.ts +0 -86
  125. package/src/screenplay/interactions/ChangeApiUrl.ts +0 -97
  126. package/tsconfig.eslint.json +0 -10
  127. /package/src/{model → models}/index.ts +0 -0
@@ -4,63 +4,73 @@ exports.LastResponse = void 0;
4
4
  const core_1 = require("@serenity-js/core");
5
5
  const abilities_1 = require("../abilities");
6
6
  /**
7
- * @desc
8
- * Provides access to the properties of the last {@link AxiosResponse} object,
9
- * cached on the {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}.
7
+ * Provides access to the properties of the last {@apilink AxiosResponse} object,
8
+ * cached on the {@apilink Ability|ability} to {@apilink CallAnApi}.
10
9
  *
11
- * @example <caption>Verify response to a GET request</caption>
12
- * import { Actor } from '@serenity-js/core';
13
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
14
- * import { Ensure, equals } from '@serenity-js/assertions';
10
+ * ## Verify response to a GET request
15
11
  *
16
- * interface Book {
17
- * title: string;
18
- * author: string
19
- * }
12
+ * ```ts
13
+ * import { actorCalled } from '@serenity-js/core'
14
+ * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
15
+ * import { Ensure, equals } from '@serenity-js/assertions'
20
16
  *
21
- * const actor = Actor.named('Apisit').whoCan(CallAnApi.at('https://myapp.com/api'));
17
+ * interface Book {
18
+ * title: string;
19
+ * author: string;
20
+ * }
22
21
  *
23
- * actor.attemptsTo(
24
- * Send.a(GetRequest.to('/books/0-688-00230-7')),
25
- * Ensure.that(LastResponse.status(), equals(200)),
26
- * Ensure.that(LastResponse.header('Content-Type'), equals('application/json')),
27
- * Ensure.that(LastResponse.body<Book>(), equals({
28
- * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
29
- * author: 'Robert M. Pirsig',
30
- * })),
31
- * );
22
+ * await actorCalled('Apisit')
23
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
24
+ * .attemptsTo(
25
+ * Send.a(GetRequest.to('/books/0-688-00230-7')),
26
+ * Ensure.that(LastResponse.status(), equals(200)),
27
+ * Ensure.that(LastResponse.header('Content-Type'), equals('application/json')),
28
+ * Ensure.that(LastResponse.body<Book>(), equals({
29
+ * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
30
+ * author: 'Robert M. Pirsig',
31
+ * })),
32
+ * )
33
+ * ```
32
34
  *
33
- * @example <caption>Use Serenity/JS adapters to navigate complex response objects</caption>
34
- * import { Actor } from '@serenity-js/core';
35
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
36
- * import { Ensure, equals } from '@serenity-js/assertions';
35
+ * ## Use Serenity/JS adapters to navigate complex response objects
37
36
  *
38
- * interface Developer {
39
- * name: string;
40
- * id: string;
41
- * projects: Project[];
42
- * }
37
+ * ```ts
38
+ * import { actorCalled } from '@serenity-js/core'
39
+ * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
40
+ * import { Ensure, equals } from '@serenity-js/assertions'
43
41
  *
44
- * interface Project {
45
- * name: string;
46
- * repoUrl: string;
47
- * }
42
+ * interface Developer {
43
+ * name: string;
44
+ * id: string;
45
+ * projects: Project[];
46
+ * }
48
47
  *
49
- * const actor = Actor.named('Apisit').whoCan(CallAnApi.at('https://myapp.com/api'));
48
+ * interface Project {
49
+ * name: string;
50
+ * repoUrl: string;
51
+ * }
50
52
  *
51
- * actor.attemptsTo(
52
- * Send.a(GetRequest.to('/developers/jan-molak')),
53
- * Ensure.that(LastResponse.status(), equals(200)),
54
- * Ensure.that(LastResponse.body<Developer>().name, equals('Jan Molak')),
55
- * Ensure.that(LastResponse.body<Developer>().projects[0].name, equals('Serenity/JS')),
56
- * );
53
+ * await actorCalled('Apisitt')
54
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
55
+ * .attemptsTo(
56
+ * Send.a(GetRequest.to('/developers/jan-molak')),
57
+ * Ensure.that(LastResponse.status(), equals(200)),
58
+ * Ensure.that(LastResponse.body<Developer>().name, equals('Jan Molak')),
59
+ * Ensure.that(LastResponse.body<Developer>().projects[0].name, equals('Serenity/JS')),
60
+ * )
61
+ * ```
62
+ *
63
+ * ## Learn more
64
+ * - [AxiosResponse](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L133-L140)
65
+ *
66
+ * @group Questions
57
67
  */
58
68
  class LastResponse {
59
69
  /**
60
- * @desc
61
- * Enables asserting on the {@link LastResponse} status
70
+ * Retrieves the status code of the {@apilink LastResponse|last response}
62
71
  *
63
- * @returns {@serenity-js/core/lib/screenplay~Question<number>}
72
+ * #### Learn more
73
+ * - [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
64
74
  */
65
75
  static status() {
66
76
  return core_1.Question.about(`the status of the last response`, async (actor) => {
@@ -68,60 +78,78 @@ class LastResponse {
68
78
  });
69
79
  }
70
80
  /**
71
- * @desc
72
- * Enables asserting on the {@link LastResponse} body
81
+ * Retrieves the body of the {@apilink LastResponse|last response}
82
+ *
83
+ * #### A type-safe approach using generics
73
84
  *
74
- * @example <caption>A type-safe approach using generics</caption>
75
- * interface Book {
76
- * title: string;
77
- * author: string
78
- * }
85
+ * ```ts
86
+ * import { actorCalled } from '@serenity-js/core'
87
+ * import { CallAnApi, LastResponse } from '@serenity-js/rest'
88
+ * import { Ensure, equals } from '@serenity-js/assertions'
79
89
  *
80
- * actor.attemptsTo(
90
+ * interface Book {
91
+ * title: string;
92
+ * author: string;
93
+ * }
94
+ *
95
+ * await actorCalled('Apisitt')
96
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
97
+ * .attemptsTo(
81
98
  * // ...
99
+ *
100
+ * // note body<T>() parameterised with type "Book"
82
101
  * Ensure.that(LastResponse.body<Book>(), equals({
83
- * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
84
- * author: 'Robert M. Pirsig',
102
+ * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
103
+ * author: 'Robert M. Pirsig',
85
104
  * })),
86
- * );
105
+ * )
106
+ * ```
87
107
  *
88
- * @example <caption>A non-type-safe approach using `any`</caption>
89
- * actor.attemptsTo(
108
+ * ## A not type-safe approach using `any`
109
+ *
110
+ * ```ts
111
+ * import { actorCalled } from '@serenity-js/core'
112
+ * import { CallAnApi, LastResponse } from '@serenity-js/rest'
113
+ * import { Ensure, equals } from '@serenity-js/assertions'
114
+ *
115
+ * await actorCalled('Apisitt')
116
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
117
+ * .attemptsTo(
90
118
  * // ...
119
+ *
120
+ * // note body<T>() parameterised with "any" or with no parameter is not type-safe!
91
121
  * Ensure.that(LastResponse.body<any>(), equals({
92
- * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
93
- * author: 'Robert M. Pirsig',
122
+ * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
123
+ * author: 'Robert M. Pirsig',
94
124
  * })),
95
- * );
96
- *
97
- * @example <caption>Retrieving an item at path using Property.of</caption>
98
- * import { Property } from '@serenity-js/core';
99
- *
100
- * actor.attemptsTo(
101
- * Ensure.that(
102
- * Property.of(LastResponse.body<Book>()).title,
103
- * equals('Zen and the Art of Motorcycle Maintenance: An Inquiry into Values'),
104
- * )
105
- * )
106
- *
107
- * @example <caption>Filtering response body using List</caption>
108
- * import { Property } from '@serenity-js/core';
109
- * import { property, startsWith } from '@serenity-js/assertions';
110
- *
111
- * actor.attemptsTo(
112
- * Ensure.that(
113
- * // imagine the API returns an array of books
114
- * List.of(LastResponse.body<Book[]>())
115
- * .where(Property.at<Book>().author, equals('Robert M. Pirsig'))
116
- * .first(),
117
- * property('title', startsWith('Zen and the Art of Motorcycle Maintenance')),
118
- * )
119
- * )
120
- *
121
- * @returns {@serenity-js/core/lib/screenplay~Question<any>}
122
- *
123
- * @see {@link @serenity-js/core/lib/screenplay/questions~Property}
124
- * @see {@link @serenity-js/core/lib/screenplay/questions~List}
125
+ * )
126
+ * ```
127
+ *
128
+ * ## Iterating over the items in the response body
129
+ *
130
+ * ```ts
131
+ * import { actorCalled } from '@serenity-js/core'
132
+ * import { CallAnApi, LastResponse } from '@serenity-js/rest'
133
+ * import { Ensure, equals } from '@serenity-js/assertions'
134
+ *
135
+ * interface Product {
136
+ * id: number;
137
+ * name: string;
138
+ * }
139
+ *
140
+ * await actorCalled('Apisitt')
141
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
142
+ * .attemptsTo(
143
+ * Send.a(GetRequest.to(`/products`)),
144
+ * List.of<Product>(LastResponse.body<{ products: Product[] }>().products)
145
+ * .forEach(({ item, actor }) =>
146
+ * actor.attemptsTo(
147
+ * Send.a(GetRequest.to(`/products/${ item.id }`)),
148
+ * Ensure.that(LastResponse.body<Product>().id, equals(item.id)),
149
+ * )
150
+ * ),
151
+ * )
152
+ * ```
125
153
  */
126
154
  static body() {
127
155
  return core_1.Question.about(`the body of the last response`, async (actor) => {
@@ -129,11 +157,24 @@ class LastResponse {
129
157
  });
130
158
  }
131
159
  /**
132
- * @desc
133
- * Enables asserting on one of the {@link LastResponse}'s headers
160
+ * Retrieves a header of the {@apilink LastResponse|last response}, identified by `name`
161
+ *
162
+ * ## Asserting on a header
134
163
  *
135
- * @param {string} name
136
- * @returns {@serenity-js/core/lib/screenplay~Question<string>}
164
+ * ```ts
165
+ * import { actorCalled } from '@serenity-js/core'
166
+ * import { CallAnApi, LastResponse } from '@serenity-js/rest'
167
+ * import { Ensure, equals } from '@serenity-js/assertions'
168
+ *
169
+ * await actorCalled('Apisitt')
170
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
171
+ * .attemptsTo(
172
+ * Send.a(GetRequest.to(`/products`)),
173
+ * Ensure.that(LastResponse.header('Content-Type'), equals('application/json')),
174
+ * )
175
+ * ```
176
+ *
177
+ * @param name
137
178
  */
138
179
  static header(name) {
139
180
  return core_1.Question.about(`the '${name}' header of the last response`, async (actor) => {
@@ -141,11 +182,22 @@ class LastResponse {
141
182
  });
142
183
  }
143
184
  /**
144
- * @desc
145
- * Enables asserting on all of the {@link LastResponse}'s headers,
146
- * returned as an object where the keys represent header names.
185
+ * Retrieves all the headers of the {@apilink LastResponse|last response}.
186
+ *
187
+ * ## Asserting on a header
188
+ *
189
+ * ```ts
190
+ * import { actorCalled } from '@serenity-js/core'
191
+ * import { CallAnApi, LastResponse } from '@serenity-js/rest'
192
+ * import { Ensure, equals } from '@serenity-js/assertions'
147
193
  *
148
- * @returns {@serenity-js/core/lib/screenplay~Question<Record<string, string>>}
194
+ * await actorCalled('Apisitt')
195
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
196
+ * .attemptsTo(
197
+ * Send.a(GetRequest.to(`/products`)),
198
+ * Ensure.that(LastResponse.headers()['Content-Type'], equals('application/json')),
199
+ * )
200
+ * ```
149
201
  */
150
202
  static headers() {
151
203
  return core_1.Question.about(`the headers or the last response`, async (actor) => {
@@ -1 +1 @@
1
- {"version":3,"file":"LastResponse.js","sourceRoot":"","sources":["../../../src/screenplay/questions/LastResponse.ts"],"names":[],"mappings":";;;AAAA,4CAA8D;AAE9D,4CAAyC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAa,YAAY;IAErB;;;;;OAKG;IACH,MAAM,CAAC,MAAM;QACT,OAAO,eAAQ,CAAC,KAAK,CAAS,iCAAiC,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC3E,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuDG;IACH,MAAM,CAAC,IAAI;QACP,OAAO,eAAQ,CAAC,KAAK,CAAI,+BAA+B,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACpE,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAS,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,IAAY;QACtB,OAAO,eAAQ,CAAC,KAAK,CAAS,QAAS,IAAK,+BAA+B,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACvF,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,OAAO;QACV,OAAO,eAAQ,CAAC,KAAK,CAAyB,kCAAkC,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC5F,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AArGD,oCAqGC"}
1
+ {"version":3,"file":"LastResponse.js","sourceRoot":"","sources":["../../../src/screenplay/questions/LastResponse.ts"],"names":[],"mappings":";;;AAAA,4CAA8D;AAG9D,4CAAyC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAa,YAAY;IAErB;;;;;OAKG;IACH,MAAM,CAAC,MAAM;QACT,OAAO,eAAQ,CAAC,KAAK,CAAS,iCAAiC,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC3E,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyEG;IACH,MAAM,CAAC,IAAI;QACP,OAAO,eAAQ,CAAC,KAAK,CAAI,+BAA+B,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACpE,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAI,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAS,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,MAAM,CAAC,IAAY;QACtB,OAAO,eAAQ,CAAC,KAAK,CAAS,QAAS,IAAK,+BAA+B,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACvF,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,OAAO;QACV,OAAO,eAAQ,CAAC,KAAK,CAA0B,kCAAkC,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC7F,OAAO,qBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAkC,CAAC,CAAC;QACxG,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AA/ID,oCA+IC"}
@@ -1 +1,2 @@
1
1
  export * from './LastResponse';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/rest",
3
- "version": "3.0.0-rc.9",
3
+ "version": "3.0.0",
4
4
  "description": "Test REST APIs with Serenity/JS",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -28,60 +28,37 @@
28
28
  "testing"
29
29
  ],
30
30
  "scripts": {
31
- "clean": "rimraf .nyc_output lib target",
32
- "lint": "eslint --ext ts --config ../../.eslintrc.yml .",
33
- "lint:fix": "npm run lint -- --fix",
34
- "test": "nyc --report-dir ../../target/coverage/rest mocha --config ../../.mocharc.yml 'spec/**/*.spec.*'",
35
- "compile": "tsc --project tsconfig.json",
36
- "site": "esdoc -c .esdoc.js"
31
+ "clean": "rimraf target",
32
+ "test": "nyc mocha --config ../../.mocharc.yml 'spec/**/*.spec.*'",
33
+ "compile": "rimraf lib && tsc --project tsconfig.build.json"
37
34
  },
38
35
  "repository": {
39
36
  "type": "git",
40
- "url": "https://github.com/serenity-js/serenity-js.git"
37
+ "url": "https://github.com/serenity-js/serenity-js.git",
38
+ "directory": "packages/rest"
41
39
  },
42
40
  "bugs": {
43
41
  "url": "https://github.com/serenity-js/serenity-js/issues"
44
42
  },
45
43
  "engines": {
46
- "node": "^14 || ^16",
47
- "npm": "^6 || ^7 || ^8"
44
+ "node": "^14 || ^16 || ^18",
45
+ "npm": "^6 || ^7 || ^8 || ^9"
48
46
  },
49
47
  "dependencies": {
50
- "@serenity-js/core": "3.0.0-rc.9",
51
- "axios": "^0.21.4"
48
+ "@serenity-js/core": "3.0.0",
49
+ "axios": "^1.3.4"
52
50
  },
53
51
  "devDependencies": {
54
- "@documentation/esdoc-template": "3.0.0",
55
52
  "@integration/testing-tools": "3.0.0",
56
- "@serenity-js/assertions": "3.0.0-rc.9",
57
- "@types/chai": "^4.3.0",
58
- "@types/mocha": "^9.0.0",
59
- "axios-mock-adapter": "^1.20.0",
60
- "mocha": "^9.1.3",
61
- "ts-node": "^10.4.0",
62
- "typescript": "^4.5.4"
53
+ "@serenity-js/assertions": "3.0.0",
54
+ "@types/chai": "^4.3.4",
55
+ "@types/mocha": "^10.0.1",
56
+ "axios-mock-adapter": "^1.21.2",
57
+ "mocha": "^10.2.0",
58
+ "mocha-multi": "^1.1.7",
59
+ "nyc": "15.1.0",
60
+ "ts-node": "^10.9.1",
61
+ "typescript": "^4.9.5"
63
62
  },
64
- "nyc": {
65
- "include": [
66
- "src/**/*.ts"
67
- ],
68
- "exclude": [
69
- "src/**/*.d.ts",
70
- "lib",
71
- "node_modules",
72
- "spec"
73
- ],
74
- "extension": [
75
- ".ts"
76
- ],
77
- "require": [
78
- "ts-node/register"
79
- ],
80
- "reporter": [
81
- "json"
82
- ],
83
- "cache": true,
84
- "all": true
85
- },
86
- "gitHead": "bc72fce0831fe6c1e4e69d5ca307d7fb5f6d2f0d"
63
+ "gitHead": "1c2fffcabd725822e6c93fb4125f5830fa97f56d"
87
64
  }
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './model';
1
+ export * from './models';
2
2
  export * from './screenplay';
@@ -0,0 +1,73 @@
1
+ import { Answerable, Question, WithAnswerableProperties } from '@serenity-js/core';
2
+ import { AxiosRequestConfig } from 'axios';
3
+
4
+ import { HTTPRequest } from './HTTPRequest';
5
+
6
+ /**
7
+ * The DELETE method requests that the origin server remove the
8
+ * association between the target resource and its current
9
+ * functionality.
10
+ *
11
+ * ## Create and then remove a resource
12
+ *
13
+ * ```ts
14
+ * import { actorCalled } from '@serenity-js/core'
15
+ * import { CallAnApi, DeleteRequest, LastResponse, PostRequest, Send } from '@serenity-js/rest'
16
+ * import { Ensure, equals, startsWith } from '@serenity-js/assertions'
17
+ *
18
+ * await actorCalled('Apisitt')
19
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
20
+ * .attemptsTo(
21
+ * // create a new test user account
22
+ * Send.a(PostRequest.to('/users').with({
23
+ * login: 'tester',
24
+ * password: 'P@ssword1',
25
+ * }),
26
+ * Ensure.that(LastResponse.status(), equals(201)),
27
+ * Ensure.that(LastResponse.header('Location'), startsWith('/users')),
28
+ *
29
+ * // delete the test user account
30
+ * Send.a(DeleteRequest.to(LastResponse.header('Location'))),
31
+ * Ensure.that(LastResponse.status(), equals(200)),
32
+ * )
33
+ * ```
34
+ *
35
+ * ## Learn more
36
+ * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE
37
+ * - https://tools.ietf.org/html/rfc7231#section-4.3.5
38
+ *
39
+ * @group Models
40
+ */
41
+ export class DeleteRequest extends HTTPRequest {
42
+
43
+ /**
44
+ * Configures the object with a destination URI.
45
+ *
46
+ * When the `resourceUri` is not a fully qualified URL but a path, such as `/products/2`,
47
+ * it gets concatenated with the URL provided to the Axios instance
48
+ * when the {@apilink Ability|ability} to {@apilink CallAnApi} was instantiated.
49
+ *
50
+ * @param resourceUri
51
+ * The URI where the {@apilink Actor}
52
+ * should send the {@apilink HTTPRequest}
53
+ */
54
+ static to(resourceUri: Answerable<string>): DeleteRequest {
55
+ return new DeleteRequest(resourceUri);
56
+ }
57
+
58
+ /**
59
+ * Overrides the default Axios request configuration provided
60
+ * when the {@apilink Ability|ability} to {@apilink CallAnApi} was instantiated.
61
+ *
62
+ * #### Learn more
63
+ * - {@apilink Answerable}
64
+ * - {@apilink WithAnswerableProperties}
65
+ * - [AxiosRequestConfig](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L75-L113)
66
+ *
67
+ * @param {Answerable<WithAnswerableProperties<AxiosRequestConfig>>} config
68
+ * Axios request configuration overrides
69
+ */
70
+ using(config: Answerable<WithAnswerableProperties<AxiosRequestConfig>>): DeleteRequest {
71
+ return new DeleteRequest(this.resourceUri, undefined, Question.fromObject(config));
72
+ }
73
+ }
@@ -0,0 +1,80 @@
1
+ import { Answerable, Question, WithAnswerableProperties } from '@serenity-js/core';
2
+ import { AxiosRequestConfig } from 'axios';
3
+
4
+ import { HTTPRequest } from './HTTPRequest';
5
+
6
+ /**
7
+ * The HTTP GET method requests a representation of the specified resource.
8
+ * It is the most frequent type of request made by consumers of a typical HTTP API.
9
+ * For this reason it's important to test every known endpoint that responds to GET requests and ensure that it
10
+ * behaves correctly.
11
+ *
12
+ * Since the GET method is used to _retrieve_ data from a server, it should be implemented
13
+ * as [safe](https://developer.mozilla.org/en-US/docs/Glossary/Safe)
14
+ * and [idempotent](https://developer.mozilla.org/en-US/docs/Glossary/Idempotent).
15
+ * This means that an identical request can be made once or several times in a row with the same effect while leaving
16
+ * the server in the same state.
17
+ *
18
+ * ## Verify response to a GET request
19
+ *
20
+ * ```ts
21
+ * import { actorCalled } from '@serenity-js/core'
22
+ * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
23
+ * import { Ensure, equals } from '@serenity-js/assertions'
24
+ *
25
+ * interface Book {
26
+ * title: string;
27
+ * author: string;
28
+ * }
29
+ *
30
+ * await actorCalled('Apisitt')
31
+ * .whoCan(CallAnApi.at('https://api.example.org/'))
32
+ * .attemptsTo(
33
+ * Send.a(GetRequest.to('/books/0-688-00230-7')),
34
+ * Ensure.that(LastResponse.status(), equals(200)),
35
+ * Ensure.that(LastResponse.body<Book>(), equals({
36
+ * title: 'Zen and the Art of Motorcycle Maintenance: An Inquiry into Values',
37
+ * author: 'Robert M. Pirsig',
38
+ * })),
39
+ * )
40
+ * ```
41
+ *
42
+ * ## Learn more
43
+ * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
44
+ * - https://tools.ietf.org/html/rfc7231#section-4.3.1
45
+ *
46
+ * @group Models
47
+ */
48
+ export class GetRequest extends HTTPRequest {
49
+
50
+ /**
51
+ * Configures the object with a destination URI.
52
+ *
53
+ * When the `resourceUri` is not a fully qualified URL but a path, such as `/products/2`,
54
+ * it gets concatenated with the URL provided to the Axios instance
55
+ * when the {@apilink Ability|ability} to {@apilink CallAnApi} was instantiated.
56
+ *
57
+ * @param resourceUri
58
+ * The URI where the {@apilink Actor}
59
+ * should send the {@apilink HTTPRequest}
60
+ */
61
+ static to(resourceUri: Answerable<string>): GetRequest {
62
+ return new GetRequest(resourceUri);
63
+ }
64
+
65
+ /**
66
+ * Overrides the default Axios request configuration provided
67
+ * when the {@apilink Ability|ability} to {@apilink CallAnApi} was instantiated.
68
+ *
69
+ * #### Learn more
70
+ * - {@apilink Answerable}
71
+ * - {@apilink WithAnswerableProperties}
72
+ * - [AxiosRequestConfig](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L75-L113)
73
+ *
74
+ * @param {Answerable<WithAnswerableProperties<AxiosRequestConfig>>} config
75
+ * Axios request configuration overrides
76
+ */
77
+ using(config: Answerable<WithAnswerableProperties<AxiosRequestConfig>>): GetRequest {
78
+ return new GetRequest(this.resourceUri, undefined, Question.fromObject(config));
79
+ }
80
+ }