- StoreKitManager: purchase, Transaction.updates, restore, finish - MembershipView: plan cards, purchase section, usage grid, compliance - MembershipService: API client for /membership/* endpoints - MembershipModels: Codable DTOs for plans/grants/transactions - Route.membership + ProfileView entry point - Products.storekit: Sandbox test products (monthly/yearly) - Remove hardcoded price fallback (displayPrice nil → 价格暂不可用) - Add MembershipModelsTests (12 tests) Co-Authored-By: Claude <noreply@anthropic.com>
62 lines
3.2 KiB
Swift
62 lines
3.2 KiB
Swift
import XCTest
|
|
@testable import AIStudyApp
|
|
|
|
final class MembershipModelsTests: XCTestCase {
|
|
|
|
func testPlanItemDecoding() throws {
|
|
let json = #"{"planCode":"premium","name":"Premium","entitlements":{"maxKnowledgeBases":10,"maxStorageBytes":10737418240,"maxFileSizeBytes":52428800,"monthlyOcrPages":50,"monthlyVisionPages":30,"monthlyChatCount":300,"monthlyAiAnalysisCount":0,"monthlyRecallCount":0,"monthlyCardGenCount":0,"monthlyQuizCount":0},"priceMonthly":2800,"priceYearly":19800}"#
|
|
let data = json.data(using: .utf8)!
|
|
let plan = try JSONDecoder().decode(PlanItem.self, from: data)
|
|
XCTAssertEqual(plan.planCode, "premium")
|
|
XCTAssertEqual(plan.entitlements?.maxKnowledgeBases, 10)
|
|
}
|
|
|
|
func testMyMembershipDecoding() throws {
|
|
let json = #"{"effectivePlan":"premium","grants":[{"source":"apple","status":"active","planCode":"premium","planName":"Premium","startedAt":"2026-01-01T00:00:00Z","expiresAt":null,"autoRenewStatus":"on","environment":"Production"}],"appAccountToken":"uuid","entitlements":null,"usageSummary":null}"#
|
|
let data = json.data(using: .utf8)!
|
|
let m = try JSONDecoder().decode(MyMembershipResponse.self, from: data)
|
|
XCTAssertEqual(m.effectivePlan, "premium")
|
|
XCTAssertEqual(m.grants.first?.source, "apple")
|
|
}
|
|
|
|
func testTransactionSubmitBodyEncoding() throws {
|
|
let body = TransactionSubmitBody(signedTransactionInfo: "test-jws")
|
|
let data = try JSONEncoder().encode(body)
|
|
let dict = try JSONSerialization.jsonObject(with: data) as? [String: String]
|
|
XCTAssertEqual(dict?["signedTransactionInfo"], "test-jws")
|
|
}
|
|
|
|
func testMembershipPlanResponseDecoding() throws {
|
|
let json = #"{"plans":[]}"#
|
|
let data = json.data(using: .utf8)!
|
|
let r = try JSONDecoder().decode(MembershipPlanResponse.self, from: data)
|
|
XCTAssertTrue(r.plans.isEmpty)
|
|
}
|
|
|
|
func testTransactionSubmitResponseDecoding() throws {
|
|
let json = #"{"transactionId":"tx-1","status":"created"}"#
|
|
let data = json.data(using: .utf8)!
|
|
let r = try JSONDecoder().decode(TransactionSubmitResponse.self, from: data)
|
|
XCTAssertEqual(r.transactionId, "tx-1")
|
|
}
|
|
|
|
func testQuizQuestionTypeChoice() { XCTAssertEqual(QuizQuestionType.from(rawValue: "choice"), .choice) }
|
|
func testQuizQuestionTypeFill() { XCTAssertEqual(QuizQuestionType.from(rawValue: "fill"), .fill) }
|
|
func testQuizQuestionTypeJudge() { XCTAssertEqual(QuizQuestionType.from(rawValue: "judge"), .judge) }
|
|
func testQuizQuestionTypeUnknown() { XCTAssertNil(QuizQuestionType.from(rawValue: "essay")) }
|
|
|
|
func testJudgeDisplayAnswer() {
|
|
XCTAssertEqual(QuizQuestionType.judge.displayAnswer(raw: "true"), "正确")
|
|
XCTAssertEqual(QuizQuestionType.judge.displayAnswer(raw: "false"), "错误")
|
|
}
|
|
|
|
func testChoiceDisplayAnswer() {
|
|
XCTAssertEqual(QuizQuestionType.choice.displayAnswer(raw: "0", options: ["氧气","氮气"]), "氧气")
|
|
XCTAssertEqual(QuizQuestionType.choice.displayAnswer(raw: "1", options: ["氧气","氮气"]), "氮气")
|
|
}
|
|
|
|
func testFillDisplayAnswer() {
|
|
XCTAssertEqual(QuizQuestionType.fill.displayAnswer(raw: "用户输入"), "用户输入")
|
|
}
|
|
}
|