@@ -201,6 +201,90 @@ class DocumentationCuratorTests: XCTestCase {
201201 XCTAssertEqual ( curationProblem. possibleSolutions. map ( \. summary) , [ " Remove '- <doc:First>' " ] )
202202 }
203203
204+ func testCurationInUncuratedAPICollection( ) throws {
205+ // Everything should behave the same when an API Collection is automatically curated as when it is explicitly curated
206+ for shouldCurateAPICollection in [ true , false ] {
207+ let assertionMessageDescription = " when the API collection is \( shouldCurateAPICollection ? " explicitly curated " : " auto-curated as an article under the module " ) . "
208+
209+ let catalog = Folder ( name: " unit-test.docc " , content: [
210+ JSONFile ( name: " ModuleName.symbols.json " , content: makeSymbolGraph ( moduleName: " ModuleName " , symbols: [
211+ makeSymbol ( id: " some-symbol-id " , kind: . class, pathComponents: [ " SomeClass " ] )
212+ ] ) ) ,
213+
214+ TextFile ( name: " ModuleName.md " , utf8Content: """
215+ # ``ModuleName``
216+
217+ \( shouldCurateAPICollection ? " ## Topics \n \n ### Explicit curation \n \n - <doc:API-Collection> " : " " )
218+ """ ) ,
219+
220+ TextFile ( name: " API-Collection.md " , utf8Content: """
221+ # Some API collection
222+
223+ Curate the only symbol
224+
225+ ## Topics
226+
227+ - ``SomeClass``
228+ - ``NotFound``
229+ """ ) ,
230+ ] )
231+ let ( bundle, context) = try loadBundle ( catalog: catalog)
232+ XCTAssertEqual (
233+ context. problems. map ( \. diagnostic. summary) ,
234+ [
235+ // There should only be a single problem about the unresolvable link in the API collection.
236+ " 'NotFound' doesn't exist at '/unit-test/API-Collection' "
237+ ] ,
238+ " Unexpected problems: \( context. problems. map ( \. diagnostic. summary) . joined ( separator: " \n " ) ) \( assertionMessageDescription) "
239+ )
240+
241+ // Verify that the topic graph paths to the symbol (although not used for its breadcrumbs) doesn't have the automatic edge anymore.
242+ let symbolReference = try XCTUnwrap ( context. knownPages. first ( where: { $0. lastPathComponent == " SomeClass " } ) )
243+ XCTAssertEqual (
244+ context. finitePaths ( to: symbolReference) . map { $0. map ( \. path) } ,
245+ [
246+ // The automatic default `["/documentation/ModuleName"]` curation _shouldn't_ be here.
247+
248+ // The authored curation in the uncurated API collection
249+ [ " /documentation/ModuleName " , " /documentation/unit-test/API-Collection " ] ,
250+ ] ,
251+ " Unexpected 'paths' to the symbol page \( assertionMessageDescription) "
252+ )
253+
254+ // Verify that the symbol page shouldn't auto-curate in its canonical location.
255+ let symbolTopicNode = try XCTUnwrap ( context. topicGraph. nodeWithReference ( symbolReference) )
256+ XCTAssertFalse ( symbolTopicNode. shouldAutoCurateInCanonicalLocation, " Symbol node is unexpectedly configured to auto-curate \( assertionMessageDescription) " )
257+
258+ // Verify that the topic graph doesn't have the automatic edge anymore.
259+ XCTAssertEqual ( context. dumpGraph ( ) , """
260+ doc://unit-test/documentation/ModuleName
261+ ╰ doc://unit-test/documentation/unit-test/API-Collection
262+ ╰ doc://unit-test/documentation/ModuleName/SomeClass
263+
264+ """ ,
265+ " Unexpected topic graph \( assertionMessageDescription) "
266+ )
267+
268+ // Verify that the rendered top-level page doesn't have an automatic "Classes" topic section anymore.
269+ let converter = DocumentationNodeConverter ( bundle: bundle, context: context)
270+ let moduleReference = try XCTUnwrap ( context. soleRootModuleReference)
271+ let rootRenderNode = converter. convert ( try context. entity ( with: moduleReference) )
272+
273+ XCTAssertEqual (
274+ rootRenderNode. topicSections. map ( \. title) ,
275+ [ shouldCurateAPICollection ? " Explicit curation " : " Articles " ] ,
276+ " Unexpected rendered topic sections on the module page \( assertionMessageDescription) "
277+ )
278+ XCTAssertEqual (
279+ rootRenderNode. topicSections. map ( \. identifiers) ,
280+ [
281+ [ " doc://unit-test/documentation/unit-test/API-Collection " ] ,
282+ ] ,
283+ " Unexpected rendered topic sections on the module page \( assertionMessageDescription) "
284+ )
285+ }
286+ }
287+
204288 func testModuleUnderTechnologyRoot( ) throws {
205289 let ( _, bundle, context) = try testBundleAndContext ( copying: " SourceLocations " ) { url in
206290 try """
0 commit comments