@@ -394,37 +394,87 @@ func TestGithubActionsSecretDriftDetection(t *testing.T) {
394394 }
395395 })
396396
397- t .Run ("destroyOnDrift false updates timestamp without recreation " , func (t * testing.T ) {
397+ t .Run ("destroyOnDrift false clears sensitive values instead of recreating " , func (t * testing.T ) {
398398 originalTimestamp := "2023-01-01T00:00:00Z"
399399 newTimestamp := "2023-01-02T00:00:00Z"
400400
401401 d := schema .TestResourceDataRaw (t , resourceGithubActionsSecret ().Schema , map [string ]interface {}{
402402 "repository" : "test-repo" ,
403403 "secret_name" : "test-secret" ,
404- "plaintext_value" : "test-value" ,
404+ "plaintext_value" : "original-value" ,
405+ "encrypted_value" : "original-encrypted" ,
405406 "destroy_on_drift" : false ,
406407 "updated_at" : originalTimestamp ,
407408 })
408409 d .SetId ("test-secret" )
409410
410- // Test the drift detection logic when destroy_on_drift is false
411+ // Simulate drift detection logic when destroy_on_drift is false
411412 destroyOnDrift := d .Get ("destroy_on_drift" ).(bool )
412- if updatedAt , ok := d .GetOk ("updated_at" ); ok && ! destroyOnDrift && updatedAt != newTimestamp {
413- // This simulates what happens when destroy_on_drift=false
413+ storedUpdatedAt , hasStoredUpdatedAt := d .GetOk ("updated_at" )
414+
415+ if hasStoredUpdatedAt && storedUpdatedAt != newTimestamp {
416+ if destroyOnDrift {
417+ // Would clear ID for recreation
418+ d .SetId ("" )
419+ } else {
420+ // Should clear sensitive values to trigger update
421+ d .Set ("encrypted_value" , "" )
422+ d .Set ("plaintext_value" , "" )
423+ }
414424 d .Set ("updated_at" , newTimestamp )
415425 }
416426
417- // Should NOT have cleared the ID
427+ // Should NOT have cleared the ID when destroy_on_drift=false
418428 if d .Id () == "" {
419429 t .Error ("Expected ID to be preserved when destroy_on_drift=false, but it was cleared" )
420430 }
421431
432+ // Should have cleared sensitive values to trigger update plan
433+ if plaintextValue := d .Get ("plaintext_value" ).(string ); plaintextValue != "" {
434+ t .Errorf ("Expected plaintext_value to be cleared for update plan, got %s" , plaintextValue )
435+ }
436+
437+ if encryptedValue := d .Get ("encrypted_value" ).(string ); encryptedValue != "" {
438+ t .Errorf ("Expected encrypted_value to be cleared for update plan, got %s" , encryptedValue )
439+ }
440+
422441 // Should have updated the timestamp
423442 if updatedAt := d .Get ("updated_at" ).(string ); updatedAt != newTimestamp {
424443 t .Errorf ("Expected timestamp to be updated to %s, got %s" , newTimestamp , updatedAt )
425444 }
426445 })
427446
447+ t .Run ("destroyOnDrift true still recreates resource on drift" , func (t * testing.T ) {
448+ originalTimestamp := "2023-01-01T00:00:00Z"
449+ newTimestamp := "2023-01-02T00:00:00Z"
450+
451+ d := schema .TestResourceDataRaw (t , resourceGithubActionsSecret ().Schema , map [string ]interface {}{
452+ "repository" : "test-repo" ,
453+ "secret_name" : "test-secret" ,
454+ "plaintext_value" : "original-value" ,
455+ "destroy_on_drift" : true , // Explicitly set to true
456+ "updated_at" : originalTimestamp ,
457+ })
458+ d .SetId ("test-secret" )
459+
460+ // Simulate drift detection logic when destroy_on_drift is true
461+ destroyOnDrift := d .Get ("destroy_on_drift" ).(bool )
462+ storedUpdatedAt , hasStoredUpdatedAt := d .GetOk ("updated_at" )
463+
464+ if hasStoredUpdatedAt && storedUpdatedAt != newTimestamp {
465+ if destroyOnDrift {
466+ // Should clear ID for recreation (original behavior)
467+ d .SetId ("" )
468+ return // Exit early like the real function would
469+ }
470+ }
471+
472+ // Should have cleared the ID for recreation when destroy_on_drift=true
473+ if d .Id () != "" {
474+ t .Error ("Expected ID to be cleared for recreation when destroy_on_drift=true, but it was preserved" )
475+ }
476+ })
477+
428478 t .Run ("default destroy_on_drift is true" , func (t * testing.T ) {
429479 d := schema .TestResourceDataRaw (t , resourceGithubActionsSecret ().Schema , map [string ]interface {}{
430480 "repository" : "test-repo" ,
@@ -463,6 +513,20 @@ func TestGithubActionsSecretDriftDetection(t *testing.T) {
463513 }
464514 })
465515
516+ t .Run ("destroy_on_drift requires ForceNew due to Update function" , func (t * testing.T ) {
517+ // Test that destroy_on_drift field has ForceNew: true
518+ // This is required because we have an Update function defined
519+ schema := resourceGithubActionsSecret ().Schema ["destroy_on_drift" ]
520+ if ! schema .ForceNew {
521+ t .Error ("destroy_on_drift field must have ForceNew: true when Update function is defined, to avoid 'Provider produced inconsistent result' errors" )
522+ }
523+
524+ // Test that it defaults to true
525+ if schema .Default != true {
526+ t .Error ("destroy_on_drift should default to true for backward compatibility" )
527+ }
528+ })
529+
466530 t .Run ("destroy_on_drift field properties" , func (t * testing.T ) {
467531 resource := resourceGithubActionsSecret ()
468532 driftField := resource .Schema ["destroy_on_drift" ]
0 commit comments