| @@ -148,3 +148,86 @@ struct CommitDetailTests { |
| 148 | } |
148 | } |
| 149 | } |
149 | } |
| 150 | } |
150 | } |
| |
151 | |
| |
152 | private func postArgv(_ stub: StubProtocol.Box) throws -> [([String], String?)] { |
| |
153 | try stub.seen.filter { $0.method == "POST" }.map { seen in |
| |
154 | let body = try #require(try JSONSerialization.jsonObject(with: seen.body) as? [String: Any]) |
| |
155 | return (try #require(body["argv"] as? [String]), body["stdin"] as? String) |
| |
156 | } |
| |
157 | } |
| |
158 | |
| |
159 | private let okCmdJSON = #"{"protocol_version":1,"exit_code":0}"# |
| |
160 | |
| |
161 | @MainActor |
| |
162 | struct AboutFileTests { |
| |
163 | |
| |
164 | /// The web's "profile-repo" form: create <owner>/.gitbay, commit a |
| |
165 | /// starter README, show the result. |
| |
166 | @Test func createsTheRepositoryAndAStarterFile() async throws { |
| |
167 | let (client, stub) = try makeClient() |
| |
168 | stub.enqueue(.init(status: 404, json: |
| |
169 | #"{"protocol_version":1,"error":"no repository cmc/.gitbay","exit_code":3}"#, |
| |
170 | match: "argv=repo&argv=show")) |
| |
171 | stub.enqueue(.init(status: 200, json: okCmdJSON, match: "cmd")) |
| |
172 | stub.enqueue(.init(status: 200, json: okCmdJSON, match: "cmd")) |
| |
173 | stub.enqueue(.init(status: 200, json: userProfileJSON, match: "argv=profile&argv=show")) |
| |
174 | let model = ProfileViewModel(client: client, name: "cmc") |
| |
175 | |
| |
176 | let created = await model.createAboutFile() |
| |
177 | |
| |
178 | #expect(created) |
| |
179 | #expect(model.actionError == nil) |
| |
180 | let writes = try postArgv(stub) |
| |
181 | #expect(writes.map(\.0) == [ |
| |
182 | ["repo", "create", "cmc/.gitbay"], |
| |
183 | ["repo", "commit-file", "cmc/.gitbay", "profile/README.md", "--ref", "main", |
| |
184 | "--message", "add profile about", "--file", "-"], |
| |
185 | ]) |
| |
186 | #expect(writes[1].1 == "# cmc\n\nThis is the about text on your profile.\n") |
| |
187 | #expect(model.state.value?.aboutPath == "profile/README.org") |
| |
188 | } |
| |
189 | |
| |
190 | /// A .gitbay repository can exist without an about file in it — it |
| |
191 | /// holds other per-owner configuration too. Creating it again would |
| |
192 | /// fail, so only the file is written. |
| |
193 | @Test func skipsCreateWhenTheRepositoryExists() async throws { |
| |
194 | let (client, stub) = try makeClient() |
| |
195 | stub.enqueue(.init(status: 200, json: |
| |
196 | #"{"protocol_version":1,"data":{"path":"krz/.gitbay"},"exit_code":0}"#, |
| |
197 | match: "argv=repo&argv=show")) |
| |
198 | stub.enqueue(.init(status: 200, json: okCmdJSON, match: "cmd")) |
| |
199 | stub.enqueue(.init(status: 200, json: orgProfileJSON, match: "argv=profile&argv=show")) |
| |
200 | let model = ProfileViewModel(client: client, name: "krz") |
| |
201 | |
| |
202 | let created = await model.createAboutFile() |
| |
203 | |
| |
204 | #expect(created) |
| |
205 | let writes = try postArgv(stub) |
| |
206 | #expect(writes.count == 1) |
| |
207 | #expect(Array(writes[0].0.prefix(4)) == ["repo", "commit-file", "krz/.gitbay", "profile/README.md"]) |
| |
208 | #expect(writes[0].1 == "# krz\n\nThis is the about text on your profile.\n") |
| |
209 | } |
| |
210 | |
| |
211 | /// A refused create must not go on to write a file into nothing. |
| |
212 | @Test func aRefusedCreateStopsAndSurfaces() async throws { |
| |
213 | let (client, stub) = try makeClient() |
| |
214 | stub.enqueue(.init(status: 404, json: |
| |
215 | #"{"protocol_version":1,"error":"no repository krz/.gitbay","exit_code":3}"#, |
| |
216 | match: "argv=repo&argv=show")) |
| |
217 | stub.enqueue(.init(status: 200, json: |
| |
218 | #"{"protocol_version":1,"error":"only admins of krz can create repositories there","exit_code":4}"#, |
| |
219 | match: "cmd")) |
| |
220 | let model = ProfileViewModel(client: client, name: "krz") |
| |
221 | |
| |
222 | let created = await model.createAboutFile() |
| |
223 | |
| |
224 | #expect(created == false) |
| |
225 | #expect(model.actionError?.isEmpty == false) |
| |
226 | #expect(try postArgv(stub).count == 1) |
| |
227 | } |
| |
228 | |
| |
229 | @Test func theAboutRepositoryIsTheOwnersDotGitbay() throws { |
| |
230 | let (client, _) = try makeClient() |
| |
231 | #expect(ProfileViewModel(client: client, name: "cmc").aboutRepo == "cmc/.gitbay") |
| |
232 | } |
| |
233 | } |