@@ -682,3 +682,105 @@ func TestUpdateCampaign_NullableFields(t *testing.T) {
682682 t .Errorf ("name should not be sent, got %v" , body ["name" ])
683683 }
684684}
685+
686+ func TestGetCampaignMetrics (t * testing.T ) {
687+ want := EmailMetrics {
688+ Sends : 4210 ,
689+ Opens : 1922 ,
690+ Clicks : 301 ,
691+ Unsubscribes : 12 ,
692+ SpamReports : 1 ,
693+ HardBounces : 9 ,
694+ SoftBounces : 13 ,
695+ }
696+
697+ tests := []struct {
698+ name string
699+ id string
700+ statusCode int
701+ body string
702+ wantAPIErr * APIError
703+ wantErrMsg string
704+ }{
705+ {
706+ name : "success" ,
707+ id : "cmp_abc123" ,
708+ statusCode : http .StatusOK ,
709+ body : `{"sends":4210,"opens":1922,"clicks":301,"unsubscribes":12,"spamReports":1,"hardBounces":9,"softBounces":13}` ,
710+ },
711+ {
712+ name : "not found" ,
713+ id : "cmp_missing" ,
714+ statusCode : http .StatusNotFound ,
715+ body : `{"message":"Campaign not found."}` ,
716+ wantAPIErr : & APIError {StatusCode : http .StatusNotFound , Message : "Campaign not found." },
717+ },
718+ {
719+ name : "invalid id" ,
720+ id : "bad" ,
721+ statusCode : http .StatusBadRequest ,
722+ body : `{"message":"Invalid campaignId"}` ,
723+ wantAPIErr : & APIError {StatusCode : http .StatusBadRequest , Message : "Invalid campaignId" },
724+ },
725+ {
726+ name : "invalid json" ,
727+ id : "cmp_abc123" ,
728+ statusCode : http .StatusOK ,
729+ body : `not json` ,
730+ wantErrMsg : "failed to decode response" ,
731+ },
732+ }
733+
734+ for _ , tt := range tests {
735+ t .Run (tt .name , func (t * testing.T ) {
736+ var gotMethod , gotPath string
737+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
738+ gotMethod = r .Method
739+ gotPath = r .URL .Path
740+ w .WriteHeader (tt .statusCode )
741+ w .Write ([]byte (tt .body ))
742+ }))
743+ defer server .Close ()
744+
745+ client := NewClient ("test-key" , WithBaseURL (server .URL ))
746+ result , err := client .GetCampaignMetrics (tt .id )
747+
748+ if tt .wantAPIErr != nil {
749+ var apiErr * APIError
750+ if ! errors .As (err , & apiErr ) {
751+ t .Fatalf ("expected *APIError, got %T: %v" , err , err )
752+ }
753+ if apiErr .StatusCode != tt .wantAPIErr .StatusCode {
754+ t .Errorf ("StatusCode = %d, want %d" , apiErr .StatusCode , tt .wantAPIErr .StatusCode )
755+ }
756+ if apiErr .Message != tt .wantAPIErr .Message {
757+ t .Errorf ("Message = %q, want %q" , apiErr .Message , tt .wantAPIErr .Message )
758+ }
759+ return
760+ }
761+
762+ if tt .wantErrMsg != "" {
763+ if err == nil {
764+ t .Fatalf ("expected error containing %q, got nil" , tt .wantErrMsg )
765+ }
766+ if ! strings .Contains (err .Error (), tt .wantErrMsg ) {
767+ t .Errorf ("error = %q, want it to contain %q" , err .Error (), tt .wantErrMsg )
768+ }
769+ return
770+ }
771+
772+ if err != nil {
773+ t .Fatalf ("unexpected error: %v" , err )
774+ }
775+ if gotMethod != http .MethodGet {
776+ t .Errorf ("method = %q, want GET" , gotMethod )
777+ }
778+ if wantPath := "/campaigns/" + tt .id + "/metrics" ; gotPath != wantPath {
779+ t .Errorf ("path = %q, want %q" , gotPath , wantPath )
780+ }
781+ if * result != want {
782+ t .Errorf ("metrics = %+v, want %+v" , * result , want )
783+ }
784+ })
785+ }
786+ }
0 commit comments